Clr Dll由测试程序加载,但不是通过调用应用程序 [英] Clr Dll loaded by test prog but not by calling app
问题描述
我想开发一个程序的插件(EXE)与外部C#模块互操作。插件是所需的三个dll之一:这个dll(A)调用一个包装dll(Native / Managed,在C ++ / Cli)(B)与C#dll(C)互操作。
A在部署时应由调用程序(EXE)加载。
显示来自C#dll的消息,这告诉我dll A由C ++测试器正确加载,随后已成功调用其他dll。
在部署中,如果EXE只显示一条消息,则会加载EXE。然而,当代码行调用dll B添加,EXE不再识别dll A。
我已经确保所有文件在正确的地方。所以我认为问题出在interop代码的额外行调用dll B.任何想法,我应该在哪里寻找问题?
这里是导出的函数Dll A:
int WINAPI Init()
{
FILE * pConsole;
AllocConsole();
freopen_s(& pConsole,CONOUT $,wb,stdout);
printf(Started \\\
);
//下面这两行调用包装器dll B
//用作dll A和C $ b之间的中间人b $ b 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
类ILBridge_ClientWrapper;
class NativeExport_ClientWrapper {
private:
ILBridge_ClientWrapper * __bridge;
public:
NativeExport_ClientWrapper();
public:
〜NativeExport_ClientWrapper();
public:
THISDLL_API void Test();
};
externCTHISDLL_API NativeExport_ClientWrapper * createMyClass();
这里是包装器的管理端:
// ----------------------------------- -----------
//ILBridge_ClientWrapper.h
// ------------------------ ----------------------
#pragma once
#pragma manage
#include< vcclr.h>
class ILBridge_ClientWrapper {
private:
gcroot< Client ^> __Impl;
public:
ILBridge_ClientWrapper(){
__Impl = gcnew Client;
}
void Test(){
__Impl-> test();
}
};
经过彻底的搜索,我发现没有什么有助于解决这个问题,包括做库负载调试。
我的其他相关发布在这里:意外的Stackoverflow异常在DLL中使用CLR
最后,通过做几件事,这个异常1)在我的CS项目中,我使用unmanagedexports包(使用NuGet包管理器来安装它:Install-Package unmanagedexports)导出静态方法使用__stdcall调用约定。在这个项目中,您需要添加这些:
使用System.Runtime.InteropServices;
使用RGiesecke.DllExport;
2)将包装器头文件的路径添加到非托管C / C ++项目的属性页/ c ++ - > general-> additional include目录)
3)将托管和本地包装器放入一个项目/ dll(使用/ clr选项构建)其他两个模块(一个用于托管C#,一个用于非托管C / C ++)
4)可选地,我为非托管C / C ++函数添加了一个定义文件
5)确保所有模块都是在相同的框架和平台上构建的。在我的例子中,我使用框架4.0和x86平台。在某些情况下,您需要添加带有以下内容的app.config文件:
< configuration&
< startup useLegacyV2RuntimeActivationPolicy =true>
< supportedRuntime version =v4.0sku =。NETFramework,Version = v4.0/>
< / startup>
< / configuration>
6)设置环境中的路径指向where dll已部署
就是这样。
I want to develop a plugin for a program (EXE) to interop with an external C# module. The plugin is one of the three dlls needed: this dll (A) calls a wrapper dll (Native/Managed, in C++/Cli) (B) to interop with a C# dll (C).
A is supposed to be loaded by a calling program (EXE) when deployed.
In testing, a message from the C# dll is displayed, which tells me dll A is correctly loaded by a C++ tester and subsequently has made successful call to other dlls.
In deployment, dll A is loaded by EXE if it only displays a message. However, when lines of code to call dll B are added, EXE no longer recognizes dll A.
I have made sure that all files are in the right place. So I think the problem lies in the extra lines of interop code to call dll B. Any idea as to where I should look for problem?
Here is the exported function in 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;
}
Here is the unmanaged side of the wrapper 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();
And here is the managed side of the wrapper:
//----------------------------------------------
//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();
}
};
After exhaustive search, I found nothing that helps to resolve this issue, including doing library load debugging.
My other related posting is here: Unexpected Stackoverflow exception using CLR in a dll
And finally, by doing several things, this exception is gone and everything works now:
1) In my CS project, I use the unmanagedexports package (use NuGet package manager to install it: Install-Package unmanagedexports) to export static methods using the __stdcall calling convention. In this project, you need to add these:
using System.Runtime.InteropServices;
using RGiesecke.DllExport;
2) add the path to the wrapper header files to the unmanaged C/C++ project's property page (C/C++->general->additional include directories)
3) put the managed and native wrapper into one project/dll (built with /clr option), separate them from the other two modules (one for the managed C# and one for the unmanaged C/C++)
4) optionally, I added a definition file for the unmanaged C/C++ functions
5) make sure all modules are built against the same framework and platform. In my case, I use framework 4.0 and x86 platform. In some case, you need to add an app.config file with the following:
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>"
6) set the path in the environment pointing to where the dlls are deployed
That's about it.
这篇关于Clr Dll由测试程序加载,但不是通过调用应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!