Click here to Skip to main content
15,883,896 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
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
C++
#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
C++
 #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;
};


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?
Posted
Updated 20-Apr-15 4:21am
v2
Comments
Sergey Alexandrovich Kryukov 20-Apr-15 11:14am    
Interesting question, my 5.
I have a good question for you: do you have this C++ source code and the possibility to update it? If you can, there is a really elegant and really reliable, non-intrusive solution.
—SA
eswarpabolu 21-Apr-15 1:28am    
i have the source code for C++ solution. But what i though was not to touch C++ source. If there is any possibility to do it in C#, it would be great.

If there is no alternative, i need to follow any one of the specified two solutions.

If u can propose some other alternative, please give u r inputs.
Sergey Alexandrovich Kryukov 21-Apr-15 9:22am    
Sure. Please see Solution 1.
—SA

1 solution

eswarpabolu wrote:
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.
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
 
Share this answer
 
v2
Comments
eswarpabolu 29-Apr-15 3:33am    
Hi,
Sorry for the delay in replying you. I was following the way u suggested.
The way how i am developing is, i am having two dll's. One managed(Bridge dll) and one unmanaged dll where the source code is same for both.
Managed dll will be built through C++/CLI.
My requirement is: The structures defined in unmanaged C++ header should be consumed by C# application via C++/CLR dll without doing any modifications.

When i declared so in unmanaged header,
1) i was not able to consume that structure in the managed C++/CLR dll as member of newly created ref class.(Error: member of a managed class cannot be of a non-managed class type). Searched and found out it needed to be declared as pointer in the ref class.
2) I was able to see only the structure name in C#. But the members of the structure is not accessable.

Any help? Sergey Alexandrovich Kryukov
Sergey Alexandrovich Kryukov 29-Apr-15 9:18am    
You need to get rid of anything unmanaged in your public or protected members of the wrapping class or structure. You can clone your unmanaged data to some managed members.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900