Load your own C/C ++ dynamic link library in C #

Source: Internet
Author: User

Load your own dynamic link library in C #

I. background
C # And the new technical solution Web Service are developed using a new language in the development of a new project. However, in the new project, some old modules need to be used, it is generally written in C, C ++, or Delphi. There are three available methods for developers to use the old module: first, rewrite the C or C ++ functions with C # completely, so that the entire project code is more unified and easy to maintain. However, although Microsoft and some books say how C # is close to C ++, it is still a very painful thing to rewrite, especially the pointer and memory operations in C ++; 2. encapsulate C or C ++ functions into com. It is convenient to call COM in C, only the conversion between the C or C ++ type and the com type needs to be processed during encapsulation, but it also has some trouble. In addition, the com needs to be registered, which may cause confusion when the number of registrations is too large; 3. encapsulate C or C ++ functions into a dynamic link library. The encapsulation process is simple and does not work much. Therefore, I decided to use the method of loading the dynamic link library to implement it. As a result, the question of how to call a custom dynamic link library in C # emerged. I searched for related topics online, I found an article calling the system API, but it does not explain how to solve this problem, and there is no detailed description on msdn. Based on this, I decided to start from a simple step by step to see if I could achieve my goal.
(Note: I am afraid of the trouble of rewriting here. The code I rewrite is a variable-length encryption algorithm function. There are more than 600 lines of code, and I am not familiar with the algorithm itself, there are too many pointer and memory operations in the algorithm. To ensure the algorithm is correct, the most feasible method is to move less code. Otherwise, as long as there is a slight error, it cannot be sure that the algorithm is compatible with the previous one)

Ii. Technical Implementation
Next, let's take a look at how to gradually implement the definition of dynamic library loading, type matching, and function export of dynamic link library. You can refer to the macro definition below:

# Define libexport_api extern "C" _ declspec (dllexport)
The first step is to start with a simple call and define a simple function, which only implements an integer addition sum:

Libexport_api int mysum (int A, int B) {return a + B ;}
C # import definition:

Public class refcomm
{
[Dllimport ("libencrypt. dll ",
Entrypoint = "mysum ",
Charset = charset. Auto, callingconvention = callingconvention. stdcall)]
Public static extern int mysum (int A, int B );
}
Call the test in C:

Int isum = refcomm. mysum (2, 3 );
Run the command and check that isum is 5. The call is correct. The first step is the completion of the test. It indicates that the custom dynamic link library function can be called in C.

Step 2: I have defined the string operation function (for simplicity, the previous function name is used) and the returned result is a string:

Libexport_api char * mysum (char * a, char * B) {sprintf (B, "% s", a); return ;}
C # import definition:

Public class refcomm
{
[Dllimport ("libencrypt. dll ",
Entrypoint = "mysum ",
Charset = charset. Auto,
Callingconvention = callingconvention. stdcall)]
Public static extern string mysum (string a, string B );
}
Call the test in C:

String strdest = "";
String strtmp = refcomm. mysum ("12345", strdest );
The strtmp value is 12345, but the strdest value is null. When I modify the dynamic link library implementation, the returned result is string B:

Libexport_api char * mysum (char * a, char * B) {sprintf (B, "% s", a) return B ;}
Modify C # import definition and change string B to ref mode:

Public class refcomm
{
[Dllimport ("libencrypt. dll ",
Entrypoint = "mysum ",
Charset = charset. Auto, callingconvention = callingconvention. stdcall)]
Public static extern string mysum (string a, ref string B );
}
Call the test again in C:

String strdest = "";
String strtmp = refcomm. mysum ("12345", ref strdest );
The strtmp and strdest operations are incorrect. They contain invisible characters. Modify the C # import definition and change charset from auto to ANSI:

Public class refcomm
{
[Dllimport ("libencrypt. dll ",
Entrypoint = "mysum ",
Charset = charset. ANSI, callingconvention = callingconvention. stdcall)]
Public static extern string mysum (string a, string B );
}
Call the test again in C:

String strdest = "";
String strtmp = refcomm. mysum ("12345", ref strdest );
The strtmp value is 12345, but the strdest value is not assigned. The second step implements the function return string, but the output fails in the function exit parameter. Modify C # import definition again, and change string B to reference (REF ):

Public class refcomm
{
[Dllimport ("libencrypt. dll ",
Entrypoint = "mysum ",
Charset = charset. ANSI, callingconvention = callingconvention. stdcall)]
Public static extern string mysum (string a, ref string B );
}
The call fails during running and cannot be continued.

Step 3: Modify the dynamic link library implementation and Change B to a double pointer:

Libexport_api char * mysum (char * a, char ** B) {sprintf (* B), "% s", a); return * B ;}
C # import definition:

Public class refcomm
{
[Dllimport ("libencrypt. dll ",
Entrypoint = "mysum ",
Charset = charset. ANSI, callingconvention = callingconvention. stdcall)]
Public static extern string mysum (string a, ref string B );
}
Call the test in C:

String strdest = "";
String strtmp = refcomm. mysum ("12345", ref strdest );
Run strtmp and strdest are both "12345". The call is correct. The third step outputs the correct output result of function exit parameters.

Step 4: Modify the dynamic link library implementation to output Integer Parameters:

Libexport_api int mysum (int A, int B, int * c) {* c = a + B; return * C ;}
C # import definition:

Public class refcomm
{
[Dllimport ("libencrypt. dll ",
Entrypoint = "mysum ",
Charset = charset. ANSI, callingconvention = callingconvention. stdcall)]
Public static extern int mysum (int A, int B, ref int C );
}
Call the test in C:

Int C = 0;
Int isum = refcomm. mysum (2, 3, ref C );
Run the command to check whether isum and C are both 5. The call is correct.
After the experiments in the above steps, I have basically mastered how to define the dynamic library function and how to define the import in C #. With this foundation, I soon implemented the call of the variable-length encryption function in C, so far.

Iii. Conclusion
In C #, call the dynamic link library function written in C ++. To export parameter output, use a pointer. For strings, use a double pointer, for the C # import definition, you need to use the reference (REF) definition.
For function return values, the C # import definition must be consistent with the c ++ dynamic library function Declaration definition. Otherwise, function call may fail. When defining the import, pay attention to the charset and callingconvention parameters. Otherwise, the call fails or the result is abnormal. During running, the dynamic link library is placed in the directory of the C # program. Here I am a dynamic link library of C #, and the two dynamic link libraries are run in the same directory.

Source: http://www.kingmx.com/article/10934

 

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.