Page 1 of 1

Creating Userlibs with Visual Studio 2008

Posted: Sat Jan 05, 2008 4:41 pm
by IceSoft
@Freak I tried this simple tutorial written by @A.I. together with VS 2008 and PB Librarymaker v4.10. Userlib is generated without any errors.
But If I use it in PureBasic 4.20 (beta1) I got an error:

Code: Select all

Unhandled exception at 0x0041364b in polink.exe: 0xC0000005: Access violation reading location 0x0286d9b9.
Can you tell me what is wrong? 1000 thanks in advance :wink:
A.I wrote:Tutorial

This is a simple tutorial on how to create a simple Userlib in Microsoft Visual C++ 6.0. We'll make a DLL that has only one function: HelloWorld(), which takes one integer parameter and returns it double back to PureBasic. For example, if you passed integer 6 it would return 12 and so on.

I'm a bit of a beginner in C++ as well and there's probably many PB users that would do things differently. Feel free to correct my mistakes or post advices.

This tutorial will advance step by step just in case you don't have that much knowkedge on VC++ and/or its user interface.

Step 1: Create a new project

1) Open VC++
2) Click File/New
3) Select Win32 Dynamic-Link Library
4) Choose a project name. I use "PBHello" here.
5) You'll be asked what type of DLL project you'd want create. Select "A simple DLL project"

Now, you should have a single project created for you. At the left you see ClassView and FileView. Click on FileView and then the project name (PBHello). DoubleClick on PBHello.cpp so we can start coding...

Step 2: Code skeleton

Add these (leave the APIENTRY):

Code: Select all

char *PB_DEBUGGER_ErrorDescription; 
HWND  PB_DEBUGGER_Window; 
int   PB_DEBUGGER_Control; 


void SendDebuggerError(char*); 

void SendDebuggerError(char *text) 
{ 
   if (PB_DEBUGGER_ErrorDescription == 0) 
   { 
      PB_DEBUGGER_ErrorDescription = text; 
      PB_DEBUGGER_Control = 2; // Halt the PureBasic program flow... 
      SendMessage(PB_DEBUGGER_Window, WM_COMMAND, 6, 1); 
   } 
}
Step 3: Project setup

In order to link and Build the DLL correctly (from the view of PureBasic) we need to set a few things up.

1) Select the project PBHello from the list on the left
2) Go Build/Configurations
3) Select "Win32 Debug" and remove it
4) Confirm and Close
5) Go Project/Settings
6) Select C/C++ tab
7) Select Category-combo/Code Generation
8 ) Set Calling Convention to __cdecl (if it's not)
9) Set Runtime-library to "Multithreaded DLL"
10) Select the Link-tab
11) Add MSVCPRT.LIB to "Object/Library modules"
12) The output file name can be just "PBHello.dll"
13) OK


Step 4: Writing the code

Each procedure/function must come in pairs: the procedure itself and its corresponding debug-version for PureBasic Debugger.

The actual procedure must use _stdcall in order to work. However, the debug function should use __cdecl convention (but don't you worry about that, we've already chosen it to be the default).

Also, the debug-function must be the type of void, so it wouldn't return anything. I'm not exactly sure how the debug thingy works, but I just check if the parameters are valid, or something... You can simply write an empty debugger function.

Always remember to put PB_ prefix to the function names. Write the following code:

Code: Select all

extern "C" int _stdcall PB_HelloWorld(int x) 
{ 
	return x*2; 
} 

extern "C" void PB_HelloWorld_DEBUG(int x) 
{ 
} 
Notice:

1) the PB_ prefix
2) _stdcall for the actual functoin (omitted in the debugger function)
3) debugger function postfix _DEBUG
4) debugger function void type (and not returning a value)

Step 5: Compile

Save and hit F7 to build. There should be no errors.
You could get warning "all references to "USER32.dll" discarded by /OPT:REF" but you can ignore it (Hit F7 again).

Go to:
"C:\Program Files\Microsoft Visual Studio\MyProjects\PBHello\Release"
(or whatever the path is)

..and see there are at least PBHello.dll and PBHello.obj

Step 6: The .Desc-file

Create a new file called PBHello.Desc into that directory.

Write this:

Code: Select all

C 
1 
MSVCRT 
OBJ 
0 
Extension1 
; 
HelloWorld, Long (integer) - Doubles the given integer
Long | DebuggerCheck
The Readme.txt has description of the .Desc file format, but I find it quite a mess (no offence, Fred ;) ) If you want, you can take a look at it here:
viewtopic.php?t=15150

Our Desc-file suggests that PBHello -function requires one parameter (Long), and returns Long. For some reason I can't compile Userlibs that omit the "|DebuggerCheck" -part, so I wrote it here, too.

If you wish to omit the quick command help, just discard all starting from "-" (still include the parentheses).

Step 7: LibraryMaker

You can find it in PureBasic\Library SDK

The objects path should be the same (notice the tailing backlash):
"C:\Program Files\Microsoft Visual Studio\MyProjects\PBHello\Release"

Enable compression, it's cool.

Hit Start and select the Desc-file from the right directory. If everything went OK, you should get no messages of any kind. Go and see PureBasic\PureLibraries. There should be PBHello. If you wish, you can move it to the Userlibraries -folder.

Step 8: Test

Now, restart PB compiler or the IDE in order to get the PureBasic compiler to recognize our new command HelloWorld.

Test with this code (debugger on and off):

Code: Select all

i=HelloWorld(34)
MessageRequester("",Str(i))
------------------------

There's still lots of questions I need to find an answer. This was my first attempt of creating a Userlib for PureBasic. This is just how I did it. I hope this proofs usefuls for all you who want to start expanding PureBasic with C++ code :)

See ya.

Posted: Wed Jan 09, 2008 2:29 am
by Fred
polink just don't seems to support VC 2008 lib format for now. Try to use VC 2005, it should work correctly.

Posted: Wed Jan 09, 2008 2:48 pm
by IceSoft
Yes. VC2005 works.

I will try it again with VC2008 today evening

Posted: Wed Jan 09, 2008 3:06 pm
by inc.
VC Express 2005 does work, even if you do link with the MSVCRT finally as shown in the desc file above? Surprise! Cause since VS 2005 the CRT linkage is handled different compared to more anxient versions of VC.
http://www.purebasic.fr/english/viewtop ... 05+express

Posted: Wed Jan 09, 2008 3:18 pm
by IceSoft
inc. wrote:VC Express 2005 does work, even if you do link with the MSVCRT finally as shown in the desc file above?
Can not speak for the Express version. I have the professional version.
But if it the same (what I think) than I can say yes.
And at home I will check the setting for VC2008 again.
Maybe I had set a wrong value anywhere.

Posted: Wed Jan 09, 2008 6:47 pm
by IceSoft
Tried with VC2008.
It is working now.

Posted: Wed Jan 09, 2008 9:30 pm
by Rook Zimbabwe
Was this as a result of .NET???

Posted: Thu Jan 10, 2008 7:20 am
by IceSoft
Rook Zimbabwe wrote:Was this as a result of .NET???
No.

Posted: Thu Jan 10, 2008 9:39 am
by inc.
Do provide your library testwise so it can be checked on a diff. machine.

Posted: Mon May 12, 2008 6:37 pm
by tomijan
IceSoft wrote
Tried with VC2008.
It is working now.
Can anybody say how to make PB library in VC2008? I make above tutorial, but isn't *.obj in output directory
thanks
tom

Posted: Tue May 13, 2008 5:24 am
by IceSoft
tomijan wrote:IceSoft wrote
Tried with VC2008.
It is working now.
Can anybody say how to make PB library in VC2008? I make above tutorial, but isn't *.obj in output directory
thanks
tom
Hope we get a improved info from Fantasie Software.
VC2008 is the nativ compiler (on Windows) now.

Posted: Tue May 13, 2008 10:00 am
by DoubleDutch
VC2008 code doesn't work on Win9x machines! :(

Posted: Tue May 13, 2008 10:04 am
by Mistrel
DoubleDutch wrote:VC2008 code doesn't work on Win9x machines! :(
I don't know about Win9x but someone found a work-around for NT:
http://groups.google.com/group/Visual-S ... afe3eb6ef5

If I understand correctly the incompatibility lies in the exe header. So a library compiled with VS2008 would not have the same compatibility problem, in theory.

Posted: Tue May 13, 2008 10:13 am
by DoubleDutch
Don't know about libs, but DLLs have a problem - I had to compile Scintilla in VS2005.