Load your own dynamic-link library in C #

Source: Internet
Author: User
Tags continue sprintf
I. Background of the occurrence
New languages are used in developing new projects to develop C # and new technical solutions WEB Service, but in the new project, some old modules need to continue to use, usually in C or C + + or Delphi written, how to use the old module for developers, there are three ways to choose: First, the C or C + + function in C # completely rewritten again, so that the whole project code more unified, maintenance is also convenient. But while Microsoft and some books say, C # and C + + How to approach, but rewriting is still very painful things, especially in C + + pointers and memory operations; second, the C or C + + functions are encapsulated into COM, in C # to invoke COM more convenient, but in the encapsulation of the C or C + + type and COM type between the conversion, there are some trouble, in addition, COM also need to register, registered more times may cause confusion; third, the C or C + + functions encapsulated into a dynamic link library, encapsulation process is simple, the workload is not large. So I decided to use the method of loading the dynamic link library to implement, the question arises as to how to invoke a custom dynamic-link library in C #, and I searched for related topics on the web, found an article calling the system API, but did not explain how to solve the problem, and there was no detailed explanation on MSDN. Based on this, I decided to start from a simple, step-by-step test to see whether to achieve their goals.
(Note: I am here to rewrite why I am afraid of trouble, I rewrite the code is a variable length encryption algorithm function, the code has more than 600 lines, the algorithm itself is unfamiliar, the algorithm pointer and memory operation too much, to ensure that the correct algorithm, the most feasible way is less code, otherwise as long as there is a little mistake, Cannot be sure the algorithm is compatible with the previous

Second, the technical realization
Below see how to gradually implement dynamic library loading, type matching, dynamic link library function export definition, this does not need to say, we refer to the following macro definition can be:

#define LIBEXPORT_API extern "C" __declspec (dllexport)
The first step, I start with a simple call, defines a simple function that only implements an integer addition summation:

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);
}
To invoke a test in C #:

int isum = refcomm.mysum (2,3);
Run the view result Isum 5, the call is correct. The first step is to demonstrate that you can call a custom dynamic-link library function in C #.

In the second step, I define the function of the string operation (for simplicity or the previous function name) and return the result to a string:

Libexport_api Char *mysum (char *a,char *b) {sprintf (b, '%s ', a); return A;}
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);
}
To invoke a test in C #:

String Strdest= "";
String strtmp= refcomm.mysum ("12345", strdest);
Run View results strtmp is "12345", but strdest is empty. I modify the dynamic link library implementation and return the result to string B:

Libexport_api Char *mysum (char *a,char *b) {sprintf (b, '%s ', a) return B;}
Modify the C # import definition to modify string B to ref:

public class Refcomm
{
[DllImport ("LibEncrypt.dll",
Entrypoint= "MySum",
Charset=charset.auto,callingconvention=callingconvention.stdcall)]
public static extern string MySum (string A, ref string B);
}
To call the test again in C #:
String Strdest= "";
String strtmp= refcomm.mysum ("12345", ref strdest);
Run view results strtmp and strdest are incorrect, with invisible characters. Then modify the C # import definition to 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);
}
To call the test again in C #:

String Strdest= "";
String strtmp= Refcomm. MySum ("12345", ref strdest);
Run the view result strtmp is "12345", but the string strdest is not assigned a value. The second step is to implement the function return string, but it is not able to output in the function exit parameter. Modify the C # import definition again, and modify 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 Run-time call failed and cannot continue.

The third step is to modify the dynamic link library implementation and modify B to a dual 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);
}
To invoke a test in C #:

String Strdest= "";
String strtmp= Refcomm. MySum ("12345", ref strdest);
Run view results strtmp and strdest are all "12345" and are invoked correctly. The third step realizes the correct output of function export parameters.

The fourth step is to modify the dynamic link library implementation to achieve the output of the integer parameter:

LIBEXPORT_API int mysum (int a,int b,int *c) {*c=a+b; return *c;}
Definition of C # import:

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);
}
To invoke a test in C #:

int c=0;
int isum= Refcomm. MySum (2,3, ref C);
Run the view results Isum and C are both 5 and are invoked correctly.
After several steps of the test, the basic grasp of how to define dynamic library functions and how to define imports in C #, and so on, I quickly realized the variable-length encryption function in C # call, to achieve this goal.

Third, the conclusion
Call the dynamic-link library function written in C + +, if export parameter output is required, use pointers, for strings, you need a double pointer, and for C # import definitions, you need to use a reference (ref) definition.
For function return values, the C # import definition and C + + dynamic library function declaration definitions need to be consistent, otherwise a function call failure occurs. When defining an import, be sure to pay attention to the CharSet and callingconvention parameters, or else cause the call to fail or result in an exception. At run time, the dynamic link library is placed in the directory of the C # program, I am here is a C # dynamic link library, two dynamic link libraries are running in the same directory.
Related Article

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.