我有一个在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社区。 p>
编辑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()