A few days ago made a C + + DLL, for Web page invocation, the Web page is made in C #.
C + + DLL is simple to do, while completing a C + + EXE call DLL debugging. All ok!
The DLL is then transferred to the test in C #, and it is found that the call failed without the data.
C # calls C + + DLLs is it really such a hassle?
The C + + DLL provides a feature that converts a string into another string and then displays the transferred string on the Web page.
The interface of C + + is initially designed to:
1 /* 3 * Parameters: (in) pcinstr user input string 4 * (in) Iinlen The length of the string entered by the user 5 * (out) Pcoutstr output string 6 * (in) Ilen the maximum length of the output string 7 */ 8 BOOL Func (unsigned char *pcinstr,int iinlen,unsigned char *pcoutstr,int Ilen);
This function has only one return value, through the third argument: Pcoutstr, the other is input.
C # By this interface, the invocation method is as follows:
1 Public Static extern Char [] Func (refcharrefint iinlen,refchar[] pcoutstr,ref int ilen);
There was no problem with the compilation, but the runtime found that the value passed in by Iinlen and Ilen was incorrect.
Because the function in the DLL is judged by the argument validity, the length is not valid and will be returned directly.
Adding the MessageBox to the test shows the value of this two Len, suggesting that the values of the two parameters are the same as random numbers, each run with a different number, but the incoming data is always fixed.
If ref is not used except for the third parameter, the passed Len value is no problem. However, the runtime will produce an exception!
Check for a long while did not find out the reason, helpless, had to modify the DLL interface: Do not use parameters to pass the value, modify the return value.
The C + + interface in the DLL is modified to:
1 Char Char *pcinstr,int iinlen);
C # By this interface, the calling method tried the following two kinds:
1 (1publicstaticexternchar[] Func (charint Iinlen); 2 (2publicstaticexternstring Func (Char int iinlen);
Occurs when the interface to the calling DLL is executed at run time.
Write a C # from the Call DLL test program, the same exception occurred, the exception information is:
Additional information:cannot Marshal ' return value ': Invalid managed/unmanaged type combination.
Finally, modify the calling method to:
1 Public Static extern StringBuilder Func (charint iinlen);
When called, the interface of the DLL is called, no exception occurs, but the return value is always empty.
The suspect is that the interface in the DLL does not return a value, so add a MessageBox to display the returned data before the interface in the DLL finally returns data.
After running, it is found that the C + + interface in the DLL is called by C #, and the MessageBox displays the normal data. Consistent with the data displayed when the DLL is called by C + + EXE.
But C + + EXE can get the data, C # Web program can only get a NULL value.
The final suspicion is that C + + and C # programs run in different spaces, causing this problem.
Because in the C + + interface of the DLL, the return value is defined as an array in the interface function, and the suspect array is released when the C # call returns.
This array definition is moved from the interface to the interface, defined as a global variable, and no other changes are made.
At this point, you can also get the correct data when you find that a C # Web program calls an interface in a C + + DLL.
Summarize:
There are two issues to note when C # calls a C + + DLL:
(1) Conversion between data types, especially pointers;
(2) Run scope.
One problem that has been unresolved is the problem of ref value. Why does the data change in a C + + DLL with the value of the int type passed by ref?
I have basically not used C #, and I can't solve it.
The Final Solution: Restore the interface for the first four parameters, and the declaration interface for C # is defined as follows:
1 Public Static extern BOOL Func (charint Iinlen, [Out,marshalas (UnmanagedType.LPArray)]charint ilen);
C # Invoke DLL summary written by C + +