Clr Dll由测试编程加载,但不是通过调用app

时间:2015-02-26 23:56:01

标签: c# c++ dll interop loading

我想开发一个程序插件(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();

    }

};

1 个答案:

答案 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部署位置的路径

就是这样。