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

时间:2013-12-08 03:30:26

标签: c# c++ dll

我做了很多搜索和测试,但我无法让它正常工作。 我正在使用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#代码:

尝试重新创建要传入的Struct:

[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#程序从任何CPU更改为x86,现在我收到此错误:

WindowRecreatorGUI.exe中出现未处理的“System.EntryPointNotFoundException”类型异常

其他信息:无法在DLL“WindowRecreatorDLL.dll”中找到名为“WindowRecreatorCall”的入口点。

睡前编辑3:

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

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

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

1 个答案:

答案 0 :(得分:1)

您的本机方法接受指向结构的指针。

在C#中,它成为ref参数:

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

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