Recently, it helped the underlying development and re-encapsulated the dll with C #, that is, the methods in C ++ Dll were encapsulated with C # class for users to use.
Similar applications have been used before, and most of the problems occur in type conversion. However, this application is emerging one after another. So here we will summarize it for your reference, I also hope to help you.
First, repeat some basic usage methods. The specific methods will not be repeated here. There are many online methods. Like http://blog.csdn.net/sunboyljp/archive/2009/12/31/5110639.aspx
Definition in the c ++ header file:
NPD_API int NP_Init ();
Define functions in C #
[DllImport ("npd_api.dll")]
Public static extern int NP_Init ();
The basic type conversion is shown in the following table (I used it ):
BSTR -- StringBuilder
LPCTSTR -- StringBuilder
LPCWSTR -- IntPtr
Handle -- IntPtr
Hwnd -- IntPtr
Char * -- string
Int * -- ref int
Int & -- ref int
Void * -- IntPtrs
Unsigned char * -- ref byte
BOOL -- bool
DWORD -- uint or int (I use uint, no problem)
My questions have come, and I have learned some long-term lessons:
1. When the pointer is used as a parameter, the ref or out keyword must be used in C #, especially the struct pointer. It is not appropriate to report memory read errors even if no error data is reported. Haha
SIPCLIENT_API void WINAPI SCCleanup (SipClient * psip );
[DllImport ("sipclient. dll")]
Public static extern void SCCleanup (ref SipClient psip );
SipClient is a struct.
2. When rewriting a struct, you must specify the type length or array length before marking it, or cause a memory error.
Code
Typedef struct {
Char sDVRIP [16];/* dvr ip Address */
Char sDVRIPMask [16];/* dvr ip Address Mask */
DWORD dwNetInterface;/* 10 M/M Adaptive, Index */
WORD wDVRPort;/* Port Number */
BYTE byMACAddr [MACADDR_LEN];/* physical address of the server */
} NET_POSA_ETHERNET;
Public struct NET_POSA_ETHERNET
{
[Financialas (UnmanagedType. ByValTStr, SizeConst = 16)]
Public string sDVRIP; // dvr ip Address
[Financialas (UnmanagedType. ByValTStr, SizeConst = 16)]
Public string sDVRIPMask; // dvr ip Address Mask
Public uint dwNetInterface; // Network Interface 1-10MBase-T 2-10MBase-T full duplex 3-100MBase-TX 4-100M full duplex 5-10 M/100M adaptive
Public uint wDVRPort; // port number
[Financialas (UnmanagedType. ByValArray, SizeConst = 6)]
Public byte [] byMACAddr; // [MACADDR_LEN]; // PPPoE user name // server physical address
}
3. if you encounter such a problem, you may have to wait for a long time-http://space.cnblogs.com/q/16616 /.
Finally, we made some modifications in C ++. By setting the module definition (. def) file, we can define the name of the export function in a unified manner. IntPtr can also be used for functions whose return value is struct pointer.
Code
SIPCLIENT_API SipClient* SCInit(const char * reaml, const char * from_ip, int from_port, const char * to_ip, int to_port, const char * server_id, const char * user_id, const char * user_name, void * user_obj_param);
[DllImport("sipclient.dll")]
public static extern IntPtr SCInit(string reaml, string from_ip, int from_port,
string to_ip, int to_port, string server_id,
string user_id, string user_name, IntPtr user_obj_param);
IntPtr client = IntPtr. Zero;
Client = SIPCLIENT_API.SCInit (REALM, CLIENT_IP, CLIENT_PORT, SERVER_IP, SERVER_PORT, SERVER_ID, USER_ID, USER_ID, IntPtr. Zero );
If (client! = IntPtr. Zero)
Sipclient = (SipClient) Marshal. PtrToStructure (client, typeof (SipClient ));
Else
MessageBox. Show ("SipClient initialization failed! ");
4. Later, I encountered a crash problem caused by the callback function, which was delayed for more than half a day. When I got off work, I got delayed and finally found a solution.
At the beginning, my colleagues analyzed the cause of the crash, which was caused by recycling methods. For details, refer to http://www.hudong.com/wiki/winapiand try to use javasstdcall.
Later, the practice proved that the program was very rigorous, and the error could not be caused only when there were no errors. The idea was still _ stdcall, but there were few changes. There were two places to change, in order to ensure that no error occurs.
See http://hi.baidu.com/tease/blog/item/1fe7213802780f22b9998f5a.html.
The key is the two statements.
Typedef void (_ stdcall * CiCiCallBack) (bool started, void * client, char * message );
Modify the export function:
Extern "C" _ declspec (dllexport) bool _ stdcall Test (char * fileName, CiCiCallBack callback)
At the beginning, I only modified the definition, but forgot the modification during export. I almost gave up this solution. But fortunately, the so-called persistence is a victory!
5. After encapsulation, the system always prompts that the C ++ dll cannot be found.
In the online query, it was initially determined that it was caused by the development environment and related to environment deployment. Our development environment is vs2008, and the customer's vs2010, through several attempts, finally the problem is solved.
The first consideration is that some necessary runtime libraries in C ++ are missing and there is a dependency between them, so the dll cannot be found. Check Dependency Walker to find that something is missing on the client.
However, the problem remains unsolved after the missing items are copied to the executable program directory. But still stick to this path ~
Try to install vcredist_x86.exe to check whether some runtime libraries are missing. the problem persists.
Later, when I thought about the problem, I found that it seemed to have something to do with the Releas \ Debug version of dll. I tried to ask my colleagues to change their c ++ dll to the Release version.
Because the project was done by multiple people, it took a lot of time to compile the Release version, but the problem was finally solved!
Conclusion: directly install vcredist_x86.exe. All dll versions must use Release. If you use the Debug version, you must ensure that the dll in the executable program directory is complete!
There are also a lot of detailed explanations on the Internet. I feel that this summary is very good at http://hi.baidu.com/fairysky/blog/item/e7a8?dbaa735f34=94c8.html.
If you do the program, you are afraid of problems. If you do not know the cause, you can find a solution if you know the cause!