Clr Dll由测试程序加载,但不是通过调用应用程序 [英] Clr Dll loaded by test prog but not by calling app

查看:127
本文介绍了Clr Dll由测试程序加载,但不是通过调用应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想开发一个程序的插件(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆