Page 1 of 3

Using a C library

Posted: Mon Oct 15, 2007 11:43 am
by Lazarus404
Hi Guys,

I've had PB for ages now, but keep refraining from using it. However, I've decided to pick it up and start developing. The issue I have, though, is that I'd like to use some functionality from an existing C library. I have a C .lib file, and I've downloaded the LibImporter, but the library I wish to use has structs and macros that I'd like converted, too. Can I do this with LibImporter, and if not, how do I go about including these in my PB app? I can understand if I have to use the base functions of the macro's rather than the macros themselves if need be.

Thanks,
Laz

Posted: Mon Oct 15, 2007 2:30 pm
by tinman
Try using the header converter to convert the structures. I don't know if it converts macros too, but it might.

Posted: Mon Oct 15, 2007 3:06 pm
by inc.
Beside porting the needed header file of the .lib to PB, you need to be aware which internal calling conventions of the including symbols are used in the binary/lib file.
Do have a look in the C++ Header .... if no "Extern "C" {....}" is used then you have to apply it if recompiling is possible - otherwise it wont work.
Also do look if in the Function declarations the convention "__stdcall" or its Macro has been used.
Else you have to use "ImportC" in your Purebasic header port.

Posted: Mon Oct 15, 2007 3:11 pm
by Lazarus404
I've looked at using ImportC, but can't see where I specify the location to the lib for importing... ie, where do I enter the directory of my lib file? Are there any examples of using ImportC? Can I import structures and macro's using ImportC?

Thanks,
Laz

Posted: Thu Oct 18, 2007 2:16 pm
by Lazarus404
Okay, I'm getting further with this, but have hit a stump... Say I have two functions from my lib:

Import
getString( str$ )
returnString( str )
EndImport

Now, getString accepts a string, and returns a C struct. The return string accepts the struct, and returns a string. See? Now, the problem is, how do I store the struct? And how do I represent this in PureBasic? I've tried

val = getString( "somestring" )
result = returnString( val )
Print( result )

But I receive an error saying "String expected" on the Print line...

Any ideas?

Thanks,

Posted: Thu Oct 18, 2007 2:23 pm
by byo
I'm not sure if there's a limitation on returning C structs from DLLs, but you might want to create a equivalent Structure in Purebasic and pass it as a pointer to receive the returning data.

Some of the pros can help you better than I can.
But I say trial and error is never bad. :wink:

Posted: Thu Oct 18, 2007 2:25 pm
by Irene
Maybe it works like this:

Code: Select all

MyStruct = getString("Some text...")
Result$ = returnString(MyStruct)
Debug Result$
Also make sure that since you are using Print() you need to open a console first: OpenConsole()

Posted: Thu Oct 18, 2007 2:26 pm
by Lazarus404
That doesn't sound like it would work...

I only need to store the struct. Any operations on the struct would happen in the library. I could return a pointer to the struct if it would help? How would one store a pointer to a value from a C lib?

Thanks,

Posted: Thu Oct 18, 2007 2:28 pm
by Irene
Lazarus404 wrote:That doesn't sound like it would work...

I only need to store the struct. Any operations on the struct would happen in the library. I could return a pointer to the struct if it would help? How would one store a pointer to a value from a C lib?

Thanks,
The above just would have shown the string, not store the struct..
Could you please show me the C struct? Because you need to make it a PureBasic Structure first before attempting to store the C struct.

Posted: Thu Oct 18, 2007 2:32 pm
by Lazarus404
The struct looks like

Code: Select all

typedef struct {
	val_type t;
	char* f;
} vstring;
where val_type is also a struct. It's all simple data.

Problem is, returnString doesn't return a string, so something is going on somewhere that's not right. My guess (because it's so simple) is that PB isn't storing the struct, so isn't passing it, either.

Thanks,[/code]

Posted: Thu Oct 18, 2007 2:35 pm
by Lazarus404
When I try to force result as a string type, I get the error "cannot write a numerical value into a string variable". Can I specify in the Import block that the returnString function returns a string? Otherwise, the PB compiler gets its knickers in a knot.

Thanks,

Posted: Thu Oct 18, 2007 2:35 pm
by Irene
And how does the val_type struct look like? You need to know that too.

Code: Select all

; Still unfinished, missing val_type struct
Structure val_type

EndStructure

Structure vstring
 t.val_type
 f.s
EndStructure

Posted: Thu Oct 18, 2007 2:37 pm
by Lazarus404
Actually, val_type is a typedef

Code: Select all

typedef enum {
  VAL_INT = 0xFF,
  VAL_NULL = 0,
  VAL_FLOAT = 1,
  ...
} val_type;

Posted: Thu Oct 18, 2007 2:41 pm
by Irene
Ok... try if this works:

Code: Select all

Structure vstring
 t.l
 f.s
EndStructure

MyString.vstring = getString("Some text")
Result$ = returnString(MyString)

Debug Result$

Posted: Thu Oct 18, 2007 2:45 pm
by Lazarus404
This returns

"Can't assign a value to a structure"

:(

What about storing C pointers to PB variables?

Thanks,