【发布时间】:2013-06-07 23:04:36
【问题描述】:
我在 VS2012 中以 C# 语言调用 DLL(C 编写)。 mylib.dll 是我要在 C# 中调用的本机 dll,而 mylib.dll 也将调用另一个 mylib_another.dll。
C 函数声明为:
extern DECLSPEC_DLL BOOLEAN_TYPE SetConnection(char *dev, char *addr);
在我的 C# 文件中,我将其声明为:
[DllImport("C:\\mylib.dll", EntryPoint = "SetConnection", CharSet = CharSet.Auto)]
public static unsafe extern int SetConnection(StringBuilder dev, StringBuilder addr);
当我在代码中调用它时,我发现字符串只传递了一个字符,当我将dev传递为“USB”时,本机DLL实际上只得到一个“U”。
如果我将声明更改为:
[DllImport("C:\\mylib.dll", EntryPoint = "SetConnection", CharSet = CharSet.Ansi)]
public static unsafe extern int SetConnection(StringBuilder dev, StringBuilder addr);
然后它会引发 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.
对此有什么想法吗?
已解决如下(第一个问题的答案,第二个问题的答案,那是因为mylib.dll调用了另一个本机dll,系统没有找到它)。
类似问题here:
【问题讨论】:
-
SetConnection()的这两个声明是相同的。它们应该不同吗? -
CharSet.Auto 错误,改成 Ansi。对于以“Set”开头的函数,StringBuilder很可能出错,将其设为字符串。
-
第二个是:
CharSet = CharSet.Ansi更改为 this 时,会引发 System.AccessViolationException。