c# - 如何在 C# 中使用 3rd 方 DLL
问题描述
我有一个需要在 ac# 应用程序 (.net 4.6.1) 中使用的第 3 方 DLL。这是一个 64 位的 DLL,但我也有一个 32 位的版本。
DLL在vba(excel 64位)中成功使用如下: 声明:
Private Declare PtrSafe Function TheFunction Lib "TheDLL.dll" ( _
ByVal Param1 As String _
, ByVal Param2 As String _
, ByVal Param3 As String _
, ByVal Param4 As String _
, ByVal Param5 As String _
, ByVal Param6 As String _
, ByVal Param7 As Integer) As Variant
用法:
Dim answer As Variant
answer = TheFunction(Param1, Param2, Param3, Param4, Param5, Param6, Param7)
在 c# 中,我尝试过使用:
public class WrapperClass
{
[DllImport("TheDLL.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern IntPtr TheFunction(param list...);
}
IntPtr resPtr = WrapperClass.TheFunction(Param list...);
object resObj = Marshal.GetObjectForNativeVariant(resPtr);
WrapperClass.VariantClear(resPtr);
Marshal.FreeCoTaskMem(resPtr);
resPtr = IntPtr.Zero;
MessageBox.Show("answer = " + resObj.ToString());
调用 TheFunction 时出现错误:
An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
我也试过:
public class WrapperClass
{
[DllImport("TheDLL.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern object TheFunction(param list...);
}
object resObj = WrapperClass.TheFunction(Param list...);
MessageBox.Show("answer = " + resObj.ToString());
我收到一个错误PInvoke restriction: cannot return variants
我也尝试了上述两种方法CallingConvention=CallingConvention.StdCall
,但我得到了相同的错误消息。
我究竟做错了什么?
编辑:我尝试过使用 32 位和 64 位 DLL。我还将我的项目更改为 x86 和 x64。这些的所有组合仍然会导致相同的错误消息。
更令人困惑的是,如果我从我的项目中删除 DLL(在解决方案资源管理器中 -> 右键单击 DLL -> 删除)并将我的 DllImport 行更改为 read as [DllImport("nonexistent.dll")]
,它仍然运行并给出 PInvoke 错误。我正在使用 Visual Studio 2017 社区。
编辑 2:堆栈跟踪(已删除敏感/私人信息):
System.Runtime.InteropServices.MarshalDirectiveException
HResult=0x80131535
Message=PInvoke restriction: cannot return variants.
Source=<MyApp>
StackTrace:
at <MyApp>.Model.<WrapperClass>.<TheFunction>(String <param1>, String <param2>, String <param3>, String <param4>, String <param5>, String <param6>, Int32 <param7>)
at <MyApp>.Model.PostProcess.Process() in <BaseDir>\<MyApp>\<MyApp>\Model\PostProcess.cs:line 128
at <MyApp>.Model.PostProcess..ctor() in <BaseDir>\<MyApp>\<MyApp>\Model\PostProcess.cs:line 31
at <MyApp>.App.Application_Startup(Object Sender, StartupEventArgs e) in <BaseDir>\<MyApp>\<MyApp>\App.xaml.cs:line 30
at System.Windows.Application.OnStartup(StartupEventArgs e)
at System.Windows.Application.<.ctor>b__1_0(Object unused)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
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.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at <MyApp>.App.Main()
解决方案
推荐阅读
- entity-framework - MVC 业务逻辑 + DAL + 映射 ViewModel 和 EF 模型
- pdf - 使用 itext 7 和 GlobalSign 的文档签名服务 (DSS) 签署文档
- java - 系统找不到指定的文件试图创建 .jks 文件
- html - 将动态表单建模为 React 组件
- java - 如何避免生成以太坊 DAG 进行测试?
- python - 无法在 Keras 中实例化 Xception 模型
- python - 按正确顺序导入时 Pylint 抱怨
- python - matplotlib imshow 扭曲颜色
- java - 按数据范围和另一个过滤器搜索
- .htaccess - 与 .htaccess 中的 RewriteRule 精确匹配特定单词