问题
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();
}
};
回答1:
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.
来源:https://stackoverflow.com/questions/28755114/clr-dll-loaded-by-test-prog-but-not-by-calling-app