Page 2 of 2
Posted: Thu Mar 27, 2008 1:41 pm
by IceSoft
Fred wrote: Assigning a structure to a structured PB variable is not supported natively by PureBasic.
@Fred,
Ok... you are knowing now MY biggest wish for the next PB version
Currently I getting an IMA with your *v.cpVect example ...I will look on the DLL now... Thanks.
Posted: Thu Mar 27, 2008 2:17 pm
by freak
The way a structure is returned from a function is not defined in any standard IIRC,
so it depends entirely on the compiler used to compile the dll.
So you have to find out what compiler was used and what kind of code it
generates in this situation and then adjust your PB code to it.
Or better yet, get yourself a dll/library that doesn't use structures as a return type

Posted: Thu Mar 27, 2008 7:03 pm
by iNX
Ok, i had a look at this .dll and in this case you could get the result with a bit of inline assembly.
after the function call, the two returned values are stored in CPU registers EAX and EDX, so you can retrieve them this way:
Define X.f, Y.f
call....
EnableASM
mov X, EAX
mov Y, EDX
DisableASM
I'm not sure about the order of the parameters, so maybe you could have to switch EAX and EDX
PS Thanks to Fred for listening to my lucubrations

Posted: Fri Mar 28, 2008 10:51 am
by IceSoft
@Fred,
For me it looks there is a 'BUG' on PB.
Reason:
Look on this C source example it works correct.
Code: Select all
#include <stdio.h>
#include <windows.h>
struct cpVect
{
float x;
float y;
};
typedef cpVect (*MYPROC)(float);
VOID main(VOID)
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("chipmunk-4.0.2.dll"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
printf("DLL loaded.\n");
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "cpvforangle");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
cpVect c = (ProcAdd) (1.0);
printf( "\nx: %f\n", c.x);
printf( "\ny: %f\n", c.y);
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Message via alternative method\n");
}
Posted: Fri Mar 28, 2008 12:15 pm
by Fred
You can't assume it's a bug in PB because it is working somewhere else ! Try to create a procedure returning a string in PB, create a .lib and import it in C. Now try to call it. It will never work. Is it a C bug ?
We explained what happen, it is NOT supported by PB and will never be as it's C compiler dependant. If this API was designed to be portable and usable everywhere, it fails. Guess what any other major API (Posix, Gtk, Win32, Carbon, etc.) never use this 'feature' ?
Posted: Fri Mar 28, 2008 12:23 pm
by tinman
IceSoft wrote:Reason:
Look on this C source example it works correct.
Are you using the same compiler to create the DLL as you have used for your example code? If yes, then of course it will work. The calling convention will be the same in both DLL and example.
Returning structures by value from an external DLL would be a nightmare for Fred to support because it depends on something you have no control over and have no standard to aim for. And no (standard) way to find out from a DLL or import lib what was used to create it.
This page (
http://www.programmersheaven.com/2/Calling-conventions) has some good info on the subject.