Valhalla Legends Forums Archive | C/C++ Programming | Exporting C Functions in a DLL

AuthorMessageTime
FrostWraith
OK, I am stumped!

Here is what I have gotten to work

test.c
[code]int _stdcall SendNumber() {
    return 1;
}[/code]

test.def
[code]EXPORTS
SendNumber[/code]

Then as soon as a add a parameter for the SendNumber function like so:
[code]int _stdcall SendNumber(int inputnum) {
    return inputnum;
}[/code]

It definantly does not return the correct number.
I am using GCC command line compiler.
October 18, 2006, 8:55 PM
Kp
How do you know it is returning the wrong number?  How are you calling it?  Are you trusting the linker to fix up the reference or are you locating it dynamically via GetProcAddress?
October 19, 2006, 1:58 AM
FrostWraith
You lost me there. I am calling it via VB (unfortunatly my most fluent language). It is returning strange numbers that change each time it is recompiled. And I guess I must be trusting the linker, whatever that is.
October 19, 2006, 2:10 AM
UserLoser
What does your declaration function look like for this?
October 19, 2006, 2:30 AM
FrostWraith
Private Declare Function SendNumber Lib "E:\test.dll" (inputnum As Integer) As Integer
October 19, 2006, 2:36 AM
UserLoser
Not sure if this'll change anything, but try:

[code]
Private Declare Function SendNumbe Lib "E:\Test.dll" (ByVal InputNum As Long) As Long
[/code]
October 19, 2006, 3:22 AM
FrostWraith
Strange enough, it did. Wtf? Works good for now. Here's the next problem: Strings.

Note: All that was needed was ByVal.

Also, when I compile I get this (I changed the function btw):
[quote]Warning: resolving _get_verbyte by linking to _get_verbyte@4
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups[/quote]

It compiled and worked all nicely but, I didn't like seeing errors. So i went into the def file and predefines the linking to @4 like so:
[code]EXPORTS
    get_verbyte@4[/code]

Now it cant find dll entry point.
October 19, 2006, 4:36 AM
UserLoser
[quote author=FrostWraith link=topic=15893.msg160007#msg160007 date=1161232565]
Strange enough, it did. Wtf? Works good for now. Here's the next problem: Strings.

Note: All that was needed was ByVal.

Also, when I compile I get this (I changed the function btw):
[quote]Warning: resolving _get_verbyte by linking to _get_verbyte@4
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups[/quote]

It compiled and worked all nicely but, I didn't like seeing errors. So i went into the def file and predefines the linking to @4 like so:
[code]EXPORTS
    get_verbyte@4[/code]

Now it cant find dll entry point.
[/quote]

Public Declare Function GetVersionByte Alias "#4" Lib "Whatever.dll (...) As ...
October 19, 2006, 4:26 PM
FrostWraith
If I add that, it doesn't work. Does anyone here know how to properly declare an exported fuction in a .def file. I just don't like seeing warnings.
October 19, 2006, 9:09 PM
Myndfyr
Decorate your exported function signature as

[code]
extern "C"
[/code]
October 19, 2006, 11:57 PM
dRAgoN
[quote author=FrostWraith link=topic=15893.msg160021#msg160021 date=1161292195]
If I add that, it doesn't work. Does anyone here know how to properly declare an exported fuction in a .def file. I just don't like seeing warnings.
[/quote]
eg:
[code]LIBRARY GUI

EXPORTS
CreateREB
DestroyREB
AppendTextEX
TimeStamper
InsertItem
RemoveItem
GetListViewItemText
GetListViewSelectedItem
GetItemIndex
ModifyItem
ClearListView
SetEditBoxText
GetEditBoxText
AppendEditBoxText
GetIconCode
GetPingCode
MakeTransparent
AddChat
ClearRichEdit
InitImageList
SetRgbBG
CreateLV[/code]
[code]__stdcall[/code]
October 20, 2006, 2:27 AM
FrostWraith
OK. I cannot figure out how to pass strings through my C function and return the exact same string. Is "char*" the same data type as "As String" in VB? If it is, do i need to use ByRef to retrieve it in VB? Help me.
October 21, 2006, 3:09 AM
FrostWraith
So how would I go about sending the parameter with the same data type that is char*?

O have tried:
[code]unsigned char * _stdcall get_version ()
{
    return "1.0.0";
}[/code]
October 21, 2006, 4:14 AM
UserLoser
Public Declare Function get_version lib "whatever.dll" () As Long

Lookup lstrcpy and lstrlen for this operation
October 21, 2006, 4:34 AM
FrostWraith
Thank You!

Here was the solution for anyone who ever happens to need help.
[code]char* __stdcall get_version ()
{
    char* s1;
    const char* s2 = "1.0.0";
    char* ptr;

    ptr = strcpy( s1, s2 );
    return ptr;
}[/code]

WOW! New strange problem, if I call this function 2 times i crash! Wtf? Should I set everything to null at the end of the function?
October 21, 2006, 5:11 AM
Myndfyr
[quote author=FrostWraith link=topic=15893.msg160066#msg160066 date=1161407487]
WOW! New strange problem, if I call this function 2 times i crash! Wtf? Should I set everything to null at the end of the function?
[/quote]
It's not really that strange!  Take a look at your code!  You're declaring s1, but you're never allocating memory.  You're overwriting arbitrary memory.  Very, very scary!  You should definitely allocate memory that you're going to memcpy or strcpy to!
October 21, 2006, 8:53 AM
K
That is wrong on so many levels.  I would try something like this:

[code]
int __stdcall get_version (char* out)
{
    const char* version = "1.0.0";
    strcpy( out, version);
    return strlen(version);
}
[/code]

[code]
Public Declare Function [Whatever] (ByVal out As String) As Long

Dim buffer As String
Dim len as Long

buffer = Space(255);
len = Whatever(buffer);
buffer = Left(buffer, len);
[/code]
October 21, 2006, 8:02 PM
FrostWraith
I'm starting to understand this space thing. So basically what you want to do before you call the get_version function is free up some space that can be over written by the function?  If so, should this standard be used when calling, say, a local VB function?

Also: If the length of the string is static, should I just lower the space to (in this case) 5?
October 23, 2006, 3:57 AM
Kp
Five is not sufficient.  You're forgetting the terminating null character.

You don't need to preallocate space for calls between functions in VB (as far as I know), but generally you will need to preallocate when calling between different languages.  If you were staying purely in C, you could let the callee allocate it and burden the caller with freeing it.  Strictly speaking, you can do that with VB->C as well, but it's more troublesome.
October 23, 2006, 11:49 PM

Search