.net 试图调用非托管DLL,但它总是返回垃圾值。请帮忙!

.net 试图调用非托管DLL,但它总是返回垃圾值。请帮忙!,.net,interop,.net,Interop,有人能帮我找出以下代码段的错误吗。我试图调用一个旧的DLL,花了大约3天的时间,但找不到为什么我返回的数组和字符串总是垃圾 非托管代码: typedef struct { double a; double b; }UnmanagedStruct, far *lpUnmagedStruct; //.h file: __declspec( dllexport ) double far pascal Process(lpUnmagedStruct lpStruct, int siz

有人能帮我找出以下代码段的错误吗。我试图调用一个旧的DLL,花了大约3天的时间,但找不到为什么我返回的数组和字符串总是垃圾

非托管代码:


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");
}
这是我在.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);
pascal调用约定是您的问题。它是古老的,品沃克元帅不支持它。它从左到右传递参数,pinvoke marshaller假设stdcall从右到左传递参数。改用u stdcall:

__declspec( dllexport ) 
double __stdcall Process(lpUnmagedStruct lpStruct, int size, char* szMessage, int messageSize);
下一个问题是字符串,返回字符串需要在声明中使用StringBuilder,并在调用中传递初始化的字符串:

[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();

我随意添加了messageSize参数,这是将字符串安全复制到消息缓冲区而不破坏垃圾收集堆的必要条件。

lpStruct[0]=1是如何编译的?事实上,还有很多东西无法编译。我认为您需要在Q中更加精确。字符串参数由.net封送处理程序作为in参数封送。如果你想把一个字符串从C++返回到C,你需要使用String Bu建器或者BSTR。我试图复制并使它简单。lpStruct[]=1是一个输入错误。请看这个字符串:我的答案概括了BSTR方法。下面的另一个答案演示了StringBuilder。@Hans
ManagedStruct[]myStruct
的默认编组是否有效?我倒不这么认为。我认为PASCAL在C++头文件中现在意味着STDCALL。看来我可能很难从这件事中得到一份BSTR?!!是的,很好。不要使用ref,在C端是一个非托管结构**。@Hans如果你想输入输出,你会怎么做?我现在要投票了,虽然你显然是在最高点!!在阵列上?没什么特别的,这是默认的封送处理。@Hans,从FAR PASCAL更改为u stdcall没有帮助。对于垃圾值,结果仍然相同。