我想开发一个程序插件(EXE)来与外部C#模块互操作。该插件是所需的三个dll之一:这个dll(A)调用一个包装器dll(Native / Managed,在C ++ / Cli中)(B)与C#dll(C)互操作。
部署时应该由调用程序(EXE)加载A.
在测试中,会显示来自C#dll的消息,告诉我dll A已被C ++测试人员正确加载,并随后成功调用其他dll。
在部署中,如果只显示消息,则由EXE加载dll A.但是,当添加调用dll B的代码行时,EXE不再识别dll A.
我确保所有文件都在正确的位置。所以我认为问题在于调用dll的额外行间隔代码B.任何关于我应该在哪里寻找问题的想法?
这是dll A中的导出函数:
int WINAPI Init()
{
FILE * pConsole;
AllocConsole();
freopen_s(&pConsole, "CONOUT$", "wb", stdout);
printf("Started\n");
//These two line below call the wrapper dll B
// which serves as a middle man between dlls A and C
NativeExport_ClientWrapper* client = createMyClass();
if (client) client->Test();
return 1;
}
这是包装器B的非托管端:
//----------------------------------------------
//NativeExport_ClientWrapper.h
//----------------------------------------------
//#pragma once
#pragma once
#pragma unmanaged
#define THISDLL_EXPORTS
#ifdef THISDLL_EXPORTS
#define THISDLL_API __declspec(dllexport)
#else
#define THISDLL_API __declspec(dllimport)
#endif
class ILBridge_ClientWrapper;
class NativeExport_ClientWrapper {
private:
ILBridge_ClientWrapper* __bridge;
public:
NativeExport_ClientWrapper();
public:
~NativeExport_ClientWrapper();
public:
THISDLL_API void Test();
};
extern "C" THISDLL_API NativeExport_ClientWrapper* createMyClass();
这是包装器的管理方:
//----------------------------------------------
//ILBridge_ClientWrapper.h
//----------------------------------------------
#pragma once
#pragma managed
#include <vcclr.h>
class ILBridge_ClientWrapper {
private:
gcroot<Client^> __Impl;
public:
ILBridge_ClientWrapper() {
__Impl = gcnew Client;
}
void Test() {
__Impl->test();
}
};
答案 0 :(得分:0)
经过详尽的搜索后,我发现没有什么能帮助解决这个问题,包括进行库加载调试。
我的其他相关帖子在这里:Unexpected Stackoverflow exception using CLR in a dll
最后,通过做几件事,这个例外消失了,现在一切正常:
1)在我的CS项目中,我使用unmanagedexports包(使用NuGet包管理器安装它:Install-Package unmanagedexports)来使用__stdcall调用约定导出静态方法。在此项目中,您需要添加以下内容:
using System.Runtime.InteropServices;
using RGiesecke.DllExport;
2)将包装头文件的路径添加到非托管C / C ++项目的属性页(C / C ++ - &gt; general-&gt;其他包含目录)
3)将托管和本机包装器放入一个project / dll(使用/ clr选项构建),将它们与其他两个模块分开(一个用于托管C#,一个用于非托管C / C ++)
4)可选地,我为非托管C / C ++函数添加了定义文件
5)确保所有模块都是针对相同的框架和平台构建的。在我的例子中,我使用框架4.0和x86平台。在某些情况下,您需要添加app.config文件,其中包含以下内容:
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>"
6)在环境中设置指向dll部署位置的路径
就是这样。