首页 > 解决方案 > 如何在 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()

标签: c#excelvbadll

解决方案


推荐阅读