如何在C#中使用第三方DLL

时间:2018-11-30 11:25:54

标签: c# excel vba dll

我有一个在C#应用程序(.net 4.6.1)中需要使用的第三方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尝试了上述2种方法,但是我得到了相同的错误消息。

我在做什么错了?

edit:我尝试使用32位和64位DLL。我也将项目更改为x86和x64。这些的所有组合仍然导致相同的错误消息。

更令人困惑的是,如果我从项目中删除DLL(在解决方案资源管理器中->右键单击DLL->删除),然后将DllImport行更改为[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()

0 个答案:

没有答案