Re: [ctypes-users] [SPAM] CTYPES confusion - garbage returned from DLLFunction call??
Brought to you by:
theller
From: Mark T. <met...@gm...> - 2009-06-21 15:55:31
|
"Lynton Grice" <lyn...@lo...> wrote in message news:25544.9695200243$124...@ne...... > Hi there, [snip] Please don't post in HTML. Not everyone uses a reader that supports it. It doesn't format well in a plain text reply, either. I removed all the double- and triple-spacing it had. > NOTE: I know the DLL is build up from native C file.....so I *assume* it > is > a CDLL and not a WINDLL? Not necessarily. CDLL uses __cdecl calling convention (usually the default), but WINDLL uses the __stdcall calling convention. Your DLL viewer likely can tell you. Here's what mine says about a __stdcall function, using dumpbin.exe from Visual Studio 2008. C:\WINDOWS\SYSTEM32>dumpbin /exports user32.dll | findstr SetWindowText 647 286 0001F56B SetWindowTextA = _SetWindowTextA@8 648 287 0001960E SetWindowTextW = _SetWindowTextW@8 Note the decorated name starts with _ and ends with @8. That is __stdcall decoration. __cdecl also starts with _ but won't have the @8. > Before I mention the highlighted function above maybe a smaller example > (within the SAME DLL) would explain my problem better: > > There is a simple function called "newMqString" that is defined as follows > in the C API for the DLL (retrieved from the C header files I also have > access to...): > > /** > * To create a mqstring object with the String constant variable Provided > */ > MQEXPORT mqstring newMqString(mqstring); > > And "mqstring" is defined in a file "mq_datatypes.h" as follows: > > typedef char * mqstring; > > So essentially it takes a STRING variable (char *) in my eyes and returns > a > STRING (char *) variable... > > Now this is my first bit of confusion, I *think* the code below is OK for > trying to just print the result after calling the "newMqString" function > BUT > instead of seeing a STRING print out I get some arbitrary number come back > like "9912208" > > import ctypes as c > if __name__ == "__main__": > fmq = c.cdll.LoadLibrary("fmq-native-crtl.dll") > newMqString = fmq.newMqString > newMqString.argtypes = [c.c_char_p] > newMqString.retype = c.c_char_p > result = newMqString("Hello World") > print result > > This prints out something like: 9914096 > Why would I be getting back such garbage from the function call? In the above code "retype" shoudl be "restype". Since the default restype is integer you're seeing the c_char_p memory pointer as an integer value. > Now the plot thickens.....I really need to know how to structure and call > the following function in the DLL: > > This relates to the DLL function called "newInitialContext" highlighted > above in the DLL Viewer.. > > I have looked in the C header file called "initial_context.h" and this is > the function definition: > > InitialContext newInitialContext(mqstring url, mqstring username, mqstring > passwd); > > /** > * @return a newly created InitialContext, NULL if an error occurs > */ > > So from my eyes this takes THREE STRING arguments (char *) and returns an > "InitialContext" variable. > > I think the InitialContext is just a HASHTABLE type array....used for > storing data etc..... > > struct _InitialContext; > typedef struct _InitialContext* InitialContext; > > My question is how would I define the RETYPE for this function in the > Python > code? And what would the basic structure of the call look like? > > Here is the basic code I have done.....I can debug over the line with no > errors but it still returns garbage.... > > newInitialContext = fmq.newInitialContext > newInitialContext.argtypes = [c.c_char_p, c.c_char_p, c.c_char_p] > newInitialContext = fmq.newInitialContext("http://localhost:1856", > "anonymous", "anonymous") > > If I use the DEBUG probe to look at the value of "newInitialContext" I get > the following: > > 9914297 > > What is that? This is also just a pointer value as an integer. Since this is just an opaque data structure being used as a handle value, use newInitialContext.restype = c_void_p. -Mark |