C # calling C DLL to pass char * as parameter incorrect

I am calling a DLL (C write) in C # in VS2012. mylib.dll is the native dll that I am going to call in C #, and mylib.dll will also call another mylib_another.dll.

Declaring a C function as:

extern DECLSPEC_DLL BOOLEAN_TYPE SetConnection(char *dev, char *addr); 

In my C # file, I declare it as:

 [DllImport("C:\\mylib.dll", EntryPoint = "SetConnection", CharSet = CharSet.Auto)] public static unsafe extern int SetConnection(StringBuilder dev, StringBuilder addr); 

When I call it in the code, I find that the line skips only one character, when I pass dev as "USB", the native DLL only gets "U".

If I change the declaration to:

 [DllImport("C:\\mylib.dll", EntryPoint = "SetConnection", CharSet = CharSet.Ansi)] public static unsafe extern int SetConnection(StringBuilder dev, StringBuilder addr); 

Then it will throw a System.AccessViolationException:

 System.Reflection.TargetInvocationException was unhandled HResult=-2146232828 Message=Exception has been thrown by the target of an invocation. Source=mscorlib StackTrace: at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams) at QC.QTMDotNetKernel.DotNetKernel.RunDotNetTest(Object stateObject) at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() at System.Threading.ThreadPoolWorkQueue.Dispatch() at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() InnerException: System.AccessViolationException HResult=-2147467261 Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 

Any ideas on this?

We decided, as shown below (the answer to the first question, for the second - this is because mylib.dll called another native dll, and the system did not find it).

A similar problem here:

+1
c # dll native pinvoke
source share
2 answers

When you get only one character, this usually means that you are passing a Unicode string (UTF16) to a C / C ++ function that expects an 8-bit format such as ASCII, UTF8 or ANSI.

The 16-bit Unicode format ends with one byte of its two bytes being set to zero for characters in the ASCII / ANSI range, and because the C / C ++ program treats the zero byte as the end of line character, it truncates the string.

It is easy to try using ANSI to see if this helps; change

 CharSet = CharSet.Auto 

to

 CharSet = CharSet.Ansi 
+3
source share

There are several errors in your p / invoke:

  • The calling convention looks like cdecl . It is not specified in native code, and cdecl is the most likely default value.
  • You pass a StringBuilder , which is used for out parameters. Note that I assume that both parameters are input parameters.
  • The character set is invalid. Native code receives 8-bit encoded text.
  • You do not need to use unsafe .

Adjusted Ad:

 [DllImport(@"C:\mylib.dll", CallingConvention=CallingConvention.Cdecl)] public static extern int SetConnection(string dev, string addr); 

You can omit the character set specification, since ANSI is used by default. Of course, you do not need to specify CharSet=CharSet.Ansi if you prefer to be explicit. There is no need to specify EntryPoint if it is the same name as the function you are declaring.

0
source share

All Articles