CSharp the way to invoke a DLL written by C + + __c++

Source: Internet
Author: User

Sometimes want to write something, but because the writing is not good, technology is not how to write. Often use what, learn what time, simple write point, right when is a study note. Blog on the number of times is also very few people give me a message is not how timely reply, deeply sorry.

In some special industries, such as I engaged in the GIS, geological industry, most of the software is still in the form of C/s, software is mostly products to sell. Most of these programs are CPP language to write, on the one hand, considering the efficiency problem, on the other hand, may be due to historical reasons, the creator using CPP, the successor will continue to use.

But use CPP to do the project, and will feel the clumsiness of CPP, make an interface very laborious. So if you can use the C # language to develop, use WinForm, WPF to do interface, the world will be much better. But the SOFTWARE product produces many results to want to use up is more difficult, uses C # to write again the system is a very good road, the technical difficulty is low, but the workload is big, the later maintenance is also more difficult, the most important is in the project implementation process, the time is not enough. Another idea is to the existing CPP system packaging, directly in C # calls, these days compared several methods, and finally use the CLR to encapsulate C + +, the feasibility is relatively high.

i). PInvoke

Do not need to modify C + + DLL, directly in the C # program to introduce the required interface. At the beginning feel more smooth, but the more the more trouble, in the CSharp and CPP passed between the number of groups, pass a class, need to write a lot, and MS on the document also look dizzy. Finally gave up.

1. First create a C + + ordinary DLL, from the history of the DLL to extract a few of the interfaces they want to use, exposed. (Examples from online query)?

1 2 3 4 5 6 #define SOFTWRAPPER_API extern "C" __declspec (dllexport) <br><br>//simple interface invoke SOFTWRAPPER_API int Fncppdll ( int a, int b); With incoming arrays: SOFTWRAPPER_API void testArray1 (const int N, const int n[], int & Z); With outgoing arrays: C + + cannot directly outgoing arrays, only outgoing array pointers, SOFTWRAPPER_API void testArray2 (const int M, const int n[], int *n);

2. The corresponding implementation

1. Encapsulates the underlying data into a global function and exports
2. Copy to CSharp run path after compilation?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16-17 <span style= "line-height:1.5" >softwrapper_api int fncppdll (int a, int b) </span><br>{return a+b ;          } SOFTWRAPPER_API void TestArray1 (const int N, const int n[], int & Z) {for (int i=0; i<n; i++) {      Z+=n[i];          } SOFTWRAPPER_API void TestArray2 (const int M, const int n[], int *n) {for (int i=0; i<m; i++) {      n[i]=n[i]+10; } }

After compiling the DLL, the program exposes the interfaces and can use Depends.exe to view the export.

3. In C # to call it

Create a class in C # that is designed to manage these interfaces?

1 2 3 4 5 6 7 8 9 10 11 12 13-14 namespace CSharp {<br>//3. Define a CSharp class, wrap C + + interface for easy CSharp use      class Cppdll  & nbsp;   {         [dllimport] ("CppDll.dll", CallingConvention = CALLINGCONVENTION.CDECL)]          public static extern int Fncppdll (int x, int y);             [DllImport ("CppDll.dll", EntryPoint = "#2", CallingConvention = callingconvention.cdecl)]          public static extern Double Testarray (int N, int [] n, ref int Z);             [DllImport ("CppDll.dll", EntryPoint = "#3", CallingConvention = callingconvention.cdecl)]          public static extern void Testoutarray (int N, int [] n, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] int [] Z);     }}

This definition is then invoked directly in other C # programs. where "CppDll.dll" is the DLL filename, guaranteed in C # output directory. The declared function name is either consistent with the CPP or is specified by entrypoint = "#3" without the name. Make sure the compiler can find the interface

This approach can also implement the transport of classes (using struct and IntPtr implementations in C #), but you need to rewrite the classes in CSharp, and the order of the variables, and the memory alignment, may need to worry about them. In particular, we have a lot of classes, there are nesting between classes, etc.

Ms Website has a more detailed explanation of PInvoke and Marshal technology, which can be looked up on the network according to these two keywords.

。。 How to track Debugging: Under Debug of C # Engineering properties, enable unmanaged code debugging on a check.

II) SWIG

Before using Gdal, I learned that gdal can be accessed in multiple languages and various platforms, and that the bottom layer uses C + + to write and feel good. A couple of days ago, I took a look at http://www.swig.org/.

His packaging can be the class, the interface is very good encapsulation, but the use of swig encapsulation difficult, to learn a lot of things, online evaluation, feeling is learning a new language, so did not take a step further down.

III) D-bus

This is the technology on Linux and other systems, "Dbus is a low latency, low cost, high availability of the IPC mechanism." Is Desktop-bus ", because I encapsulated the DLL is mainly data services, so at that time to consider this technical route, using Dbus to provide server-side data services, and then C # as the client direct access to the service to obtain data, it is also a good route. However, the feeling is not very formal, also give up.

On the Swig and Dbus online documents more, interested can see, a number of ideas may be used when:

IV) C++/CLI

While looking at the mashalling, the MS site is full of concepts like managed code, so it goes deeper and feels good after watching this video.

Http://www.microsoft.com/uk/msdn/nuggets/nugget/184/Wrapping-Windows-APIs-with-CCLI.aspx

Through this video to understand how to encapsulate C + + interface, but also can see how the Master programming, benefited

Managed code is simply extended on the basis of C + + so that it can be invoked. NET inside the class library and other things. Since he is C + +, then his access to C + + DLL or other C + + library, certainly is no problem. On the other hand, he supported. NET class library, so that means you can call it directly. NET, and provides a variety of transformations between C + + and. NET Types. Further, our C # project uses a DLL composed of managed code to easily access the native code. The managed code module acts as a bridge, connecting native C + + and CSharp

1. New CLR Class Library: Under New project, select the CLR in VC + +, the following class libary. After you have created it, make sure that the common Language Runtime Support property of the General property page is set to common Language Runtime (/clr)

2. Writing classes?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17-18 #pragma once    using namespace system <span style= "COLOR: #0000ff" > Using namespace System::D ATA; </SPAN>    namespace Cppsoftbridge {     Public ref class Datamanger   & nbsp;  {     public:          bool Open (<span Style= "COLOR: #0000ff" >String^</SPAN> path);          property bool isopened{              bool Get () {return m_isopened;}          };          Property array<string^>^ alldata{              array<string^>^  get ();         };         }}

The ref in front of class has the description that the class is managed and is called in C #. The same call. NET class libraries are also distinguished by the notation here, which is equivalent to a reference to a managed class.

The implementation in CPP?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16-17 using namespace System::collections::generic; using namespace system::runtime::interopservices;    using namespace Gptsoftbridge; array<string^>^ Datamanger::alldata::get () {list<string^>^ List = <span style= "COLOR: #0000ff" >g      Cnew </SPAN>List<String^> ();      TODO, here you can access the interface List->add ("1") in native C + +;      List->add ("2"); return List->toarray ();  BOOL Datamanger::open (string^ path) {return true; According to their own needs to implement can}
The point to note here is that this part is used. NET, but it is also the syntax of C + +, such as importing library is not import, or using statement. The organization of the package is not System.Collections.Generic but system::collections::generic; The request object managed code needs to use gcnew instead of new. After the application how to judge whether it is empty. Use if (p = = nullptr).   The PIN_PTR keyword converts a managed reference to a native pointer. such as: pin_ptr<byte> pbytes = & Bytearray[0];

The rest. NET's class library is directly used, C + + old Code is also used in the good.

3. Using in C #

C # uses managed code in the same way as a class library that is written using C #. Directly after adding the project reference, you can use it directly.?

1 2 3 4 Datamanger DM =

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.