Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
197 views
in Technique[技术] by (71.8m points)

c# - Writing a DLL in C/C++ for .Net interoperability

In my C# application, I would like to write a part of the code in C. I plan to write a DLL witch would be interoperable with .Net. How can I do that?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are essentially three right ways to do it:

  • Use C++/CLI. This is the optimal way if this DLL is going to be used only by .NET.
  • Use an "extern "C"" compatible API, like the Windows API itself. This is the most portable, but isn't as convenient for your callers as using a class model to represent your objects.
    • This is the best option if you really intend to write in ANSI C (not C++).
    • For this path, you write your functions as extern "C" returntype __stdcall __declspec(dllexport) func(params) { ... }
    • You should also use a "caller-provides-the-buffer" memory model, rather than returning a buffer allocated inside your library. In the cases where you do need to allocate memory for internal state, the caller should see it as an opaque handle and you should provide accessor functions for the caller to extract data. Under no circumstances should the caller be expected to deallocate memory allocated inside your library, however it is ok for the caller to ask the library to do the deallocation.
  • Use COM, or a COM-like API. Here you return (often via out parameter) a pointer to an interface, which is a class with pure virtual functions, no non-virtual functions and no data.
    • The implementation is in concrete classes derived from this abstract interface, they can have data and helper functions galore, since that doesn't affect the binary interface.
    • This is a lot more work in the library but extremely portable and easy for the consumer to use.

And there is one thing absolutely NOT to do:

  • use __declspec(dllexport) on C++ classes.

EDIT: I want to also explain some good practices for option #2 which will maximize portability and make the native C/C++ parts usable from unmanaged applications as well.

You can make that easier with a macro, the usual way of doing it is:

In your header file, all the function declarations look like

MYPROJECTAPI(returntype) PublicFunc(params);

In your project, the definition is

#define MYPROJECTAPI(returntype) 
                   extern "C" returntype __stdcall __declspec(dllexport)

In consumer projects

#define MYPROJECTAPI(returntype) 
                   extern "C" returntype __stdcall __declspec(dllimport)

and then you can define the macro differently for other compilers like gcc which don't use __declspec.

The complete solution would look like (in public header file myproject.h):

#if _WIN32
#  if BUILDMYPROJECT
#    define MYPROJECTAPI(returntype) 
         extern "C" returntype __stdcall __declspec(dllexport)
#  else
#    define MYPROJECTAPI(returntype) 
         extern "C" returntype __stdcall __declspec(dllimport)
#  endif
#else
#  define MYPROJECTAPI(returntype) extern "C" returntype
#endif

and then your Visual C++ project would cause BUILDMYPROJECT to be defined when building myproject.dll


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...