从c#程序调用c++DLL,未处理的异常

Calling c++ DLL from C# Program, unhandled exception

本文关键字:未处理 异常 c++DLL 程序 调用      更新时间:2023-10-16

我做了很多搜索和测试,但一直无法正常工作。我正在使用MVS Express 2013,编译一个c++win32 DLL,我希望从c#GUI调用它。

在C++方面,我有一个导出的函数,它被传递了一个结构。该结构最初包含两个字符串,但传递已知大小的char数组似乎更容易。

C++代码:

struct runDetails{
    char requestedRuntype[32];
    char filename[32];
};

void __declspec(dllexport) WindowRecreatorCall(runDetails* incomingRunRequests);

c#代码:

正在尝试重新创建要传入的结构:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
    public struct runDetails{
        [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string requestedRuntype;
        [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string filename;
    };

设置动态DLL包装程序:

class CallWindowRecreator
    {
        [DllImport("WindowRecreatorDLL.dll", EntryPoint = "WindowRecreatorCall", CharSet = CharSet.Unicode)]
        public static extern void WindowRecreatorCall(ref runDetails runDetails);
    };

对DLL的实际调用:

runDetails testing;
testing.requestedRuntype = "Minimize";
testing.filename = "";
CallWindowRecreator.WindowRecreatorCall(ref testing);

现在,当我尝试DLL调用时,我得到了这个错误:

WindowRecreatorGUI.exe 中发生类型为"System.BadImageFormatException"的未处理异常

附加信息:试图加载格式不正确的程序。(HRESULT异常:0x8007000B)

我做了很多谷歌搜索和代码更改,我学到了很多,但我就是搞不清楚这一点。如有任何提示,我们将不胜感激。

编辑:更改代码并收到错误

编辑2:我已经将C#程序从Any CPU更改为x86,现在我得到了这个错误:

WindowRecreatorGUI.exe 中发生类型为"System.EntryPointNotFoundException"的未处理异常

附加信息:在DLL"WindowRecreatorDLL.DLL"中找不到名为"WindowRecreaterCall"的入口点。

睡前编辑3:

我在c++函数周围添加了一个extern c{}。现在我得到这个错误:

托管调试助手"PInvokeStackImbalance"在"C:\Users\Tom\workspace\WindowRecreatorGUI\WindowRecreateorGUI\bin\x86\Debug\WindowRecreatorGUI.vshost.exe"中检测到问题。

附加信息:调用PInvoke函数的WindowRecreatorGUI!WindowRecreateorGUI.CallWindowRecreator::WindowRecreaatorCall"使堆栈不平衡。这可能是因为托管PInvoke签名与非托管目标签名不匹配。请检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。

您的本机方法获取一个指向结构的指针。

在C#中,它变成了ref参数:

[DllImport("WindowRecreatorDLL.dll", EntryPoint = "WindowRecreatorCall", CharSet = CharSet.Unicode)]
public static extern void WindowRecreatorCall(ref runDetails runDetails);

您还需要在属性中传递正确的CallingConvention,它可能是Cdecl