Tried to call an unmanaged DLL, but it always returns junk values. Please help!
Could someone please help me figure out what is wrong with the following code snippet. I tried to call an old DLL and have spent about 3 days but couldn't find why my returned array and the string is always junk.
Unmanaged Codes:
typedef struct
{
double a;
double b;
}UnmanagedStruct, far *lpUnmagedStruct;
//.h file:
__declspec( dllexport ) double far pascal Process(lpUnmagedStruct lpStruct, int size, char far szMessage[]);
//.cpp
extern double far pascal Process(lpUnmagedStruct lpStruct, int size, char far szMessage[])
{
//Please pay attention here. It's being seen as a pointer to an array
lpStruct[0] = ...
lpStruct[2] = ...
_fstrcpy (szMsg, "Welcome");
}
And here's my codes in the .NET:
[StructLayout(LayoutKind.Sequential)]
public struct ManagedStruct
{
public double a;
public double b;
}
[DllImport("MyDll.dll", EntryPoint="Process", CharSet = CharSet.Ansi)]
public static extern double Process([In, Out]ManagedStruct[] myStruct, int size, string message);
//Implementation
ManagedStruct[] arrayOfStr开发者_运维知识库uct = new ManagedStruct[3];
string message;
//Assign values to arrayOfStruct
//Call interop
Process(arrayOfStruct, 3, message);
The pascal calling convention is your problem. It is ancient, the pinvoke marshaller doesn't support it. It passes arguments left-to-right, the pinvoke marshaller is assuming stdcall so passes them right-to-left. Use __stdcall instead:
__declspec( dllexport )
double __stdcall Process(lpUnmagedStruct lpStruct, int size, char* szMessage, int messageSize);
Next problem is the string, returning one requires you to use a StringBuilder in the declaration and pass an initialized one in the call:
[DllImport("MyDll.dll", EntryPoint="Process", CharSet = CharSet.Ansi)]
public static extern double Process(ManagedStruct[] myStruct, int size, StringBuilder message, int messageSize);
...
var buffer = new StringBuilder(666);
double retval = Process(arrayOfStruct, 3, buffer, buffer.Capacity);
var message = buffer.ToString();
I took the liberty of adding the messageSize argument, required to safely copy the string into the message buffer without risking destroying the garbage collected heap.
精彩评论