在未导出成员函数时,从C#调用C ++非托管成员函数?

在未导出成员函数时,从C#调用C ++非托管成员函数?

问题描述:

我有一个非托管DLL只导出一个C风格的工厂方法,该方法返回一个类的新实例(这里简化为简单)。



你好。 h $>

I have an unmanaged DLL that exports only a C style factory method that returns a new instance of a class (simplified here to look simple).

hello.h

#if defined(HWLIBRARY_EXPORT) // inside DLL
#   define HWAPI   __declspec(dllexport)
#else // outside DLL
#   define HWAPI   __declspec(dllimport)
#endif

struct HelloWorld{
   public:
    virtual void sayHello() = 0;
    virtual void release() = 0;
};
extern "C" HWAPI HelloWorld* GetHW();





hello.cpp



hello.cpp

 #include "hello.h"

struct HelloWorldImpl : HelloWorld
{
    void sayHello(){
        int triv;
        std::cout<<"Hello World!";
        std::cin>>triv;
    };
    void release(){
        this->HelloWorldImpl::~HelloWorldImpl();
    };
};
HelloWorld* GetHW(){
    HelloWorld* ptr = new HelloWorldImpl();
    return ptr;
};





现在,我可以使用dllimport访问GetHW()但是有没有办法访问成员函数返回的'struct'...即,你好和释放?



这个问题之前被问过一段时间。我也遇到了同样的问题。



当我用Google搜索时,能够找到两个解决方案。



解决方案1:为现有的dll公开C风格的所有成员函数。我不能这样做,因为它是第三方dll。



解决方案2:编写一个托管的C ++ dll,展示本机C ++ dll的功能,后来可以用于你的C#dll。这里有许多类/函数。因此,创建将花费大部分时间。



i从以下链接获得上述解决方案。

如何制作C ++类 [ ^ ]





如果有任何信息,请告诉我除上述两种解决方案之外的更好的解决方案?



Now, I can use dllimport to access GetHW() but is there a way to access the member functions of the returned 'struct'... ie, sayHello and release?

This question was asked a while before. I was also stuck with the same problem.

When i googled, able to find out two solutions.

Solution1: Expose all the member functions in the C-style for the existing dll. Which i cant do, as it is a 3rd party dll.

Solution2: Write a managed C++ dll exposing the functionality of native C++ dll, which later can be used in your C# dll. Here many classes/functions are present. So, creating would take most of the time.

i got the above solutions from the link below.
How to Marshal a C++ Class[^]


Please let me know if there is any better solution other than the above two solutions?

eswarpabolu写道:
eswarpabolu wrote:

I拥有C ++解决方案的源代码。但是,我不会触及C ++源代码。如果有可能在C#中做到这一点,那就太棒了。

I have the source code for C++ solution. But what iI though was not to touch C++ source. If there is any possibility to do it in C#, it would be great.

我仍然建议你修改C ++源码,因为它会给你带来很大的好处。但是您不需要修改任何代码。你可以做得更好:只以最不引人注目的方式在代码中添加一些新文件,这样你的当前功能就不会受到损害。



这个想法是:您可以使用C ++ / CLI(不仅仅是本机C ++),并且实际上使用CLI部分来将一些代码公开为托管。您可以同时使C ++项目混合模式(托管+非托管)C ++ / CLI模块和.NET程序集具有双重用途:.NET程序集可以像任何其他程序集一样引用您的C ++ / CLI程序集,并且不受管理本机单元可以继续使用其可执行模块(在本例中为DLL)作为任何其他本机DLL。



因为您可以在C ++中*混合托管代码和非托管代码CLI,您可以将本机类包装到托管的 ref CLI类型中,并使用 public 访问修饰符。最好不要更改任何现有文件,只需添加一些单独的文件。



这样,尽管有一些代码开销,似乎最有利,因为它是最可靠和可维护:您不会依赖编组的细微差别和类型的内部表示;此外,对要暴露的类型的修改可以是无痛的。



请参阅:https://msdn.microsoft.com/en-us/library/ms235282.aspx [ ^ ]。



参见:

http://en.wikipedia.org/wiki/C%2B%2B/CLI [ ^ ],>
http://www.ecma-international.org/publications/standards/Ecma -372.htm [ ^ ],

http://www.gotw.ca/publications/ C ++ CLIRationale.pdf [ ^ ],

http://blogs.msdn.com/hsutter/archive/2003/11/23/53519.aspx [ ^ ]。



另见我过去的答案:

如何在ASP.NET中调用C ++ DLL? [ ^ ],

如何在托管c ++类中捕获本机c ++异常? [ ^ ],

处理Windows窗体应用程序 [ ^ ]。



-SA

I still suggest you to modify C++ source, because it would give you a serious benefit. But you don't need to modify any code. You could do a lot better: only add some new file(s) to the code in most unobtrusive way, so your present functionality would not be compromised.

The idea is: you can use C++/CLI (not just native C++) and essentially use "CLI" part of it to expose some code as managed. You can make you C++ project mixed-mode (managed+unmanaged) C++/CLI module and .NET assembly at the same time, with possibility of dual use: .NET assemblies can reference your C++/CLI assembly as any other assembly, and unmanaged native units can just keep using its executable module (DLL, in this case) as any other native DLL.

As you can freely mix managed and unmanaged code in C++/CLI, you could wrap you native class(es) into managed "ref" CLI types and exposed those you need to expose to other assemblies using public access modifier. It's better not to change any existing files, just add some separate ones.

This way, despite of some code overhead, seems to most beneficial, because it is the most reliable and maintainable: you won't be dependent on the subtleties of marshaling and internal representation of types; moreover, modification of the types to be exposed can be painless.

Please see: https://msdn.microsoft.com/en-us/library/ms235282.aspx[^].

See also:
http://en.wikipedia.org/wiki/C%2B%2B/CLI[^],
http://www.ecma-international.org/publications/standards/Ecma-372.htm[^],
http://www.gotw.ca/publications/C++CLIRationale.pdf[^],
http://blogs.msdn.com/hsutter/archive/2003/11/23/53519.aspx[^].

And see also my past answers:
How to invoke C++ DLL in ASP.NET?[^],
How do I catch native c++ exception in managed c++ class?[^],
Dealing with windows form application[^].

—SA