Tried to call an unmanaged DLL, but it always returns junk values. Please help!

笑着哭i 提交于 2019-12-25 06:38:52

问题


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[] arrayOfStruct = new ManagedStruct[3];
string message;

//Assign values to arrayOfStruct

//Call interop
Process(arrayOfStruct, 3, message);


回答1:


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.



来源:https://stackoverflow.com/questions/5425069/tried-to-call-an-unmanaged-dll-but-it-always-returns-junk-values-please-help

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!