У меня есть сторонняя DLL, которую мне нужно использовать в приложении ac # (.net 4.6.1).Это 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
Я также попробовал 2 вышеуказанных метода с CallingConvention=CallingConvention.StdCall
, но я получаю те же сообщения об ошибках.
Что я делаю не так?
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()