我无法让我的C#Dll与我的Excel宏启用电子表格一起调用Dll中的函数。如果函数没有参数,我可以调用该函数,能够返回预期的值。但是当我向函数添加输入参数时,我无法从VBA获得成功的Dll调用。
我的C#模块的总和如下:
using System;
using System.Runtime.InteropServices;
using RGiesecke.DllExport;
namespace RSExternalInterface
{
public class RSExternalInterface
{
[DllExport("add", CallingConvention = CallingConvention.Cdecl)]
public static int TestExport(int left, int right)
{
return left + right;
}
}
}
我的VBA代码如下。
模块声明:
Declare Function add Lib "C:\Program Files\RS\RSExternalInterface.dll" (ByVal Left As Integer, ByVal Right as Integer) As Integer
在按钮的click事件子区域内调用上面的函数,如下所示:
result = add (5, 7)
执行上述行的那一刻,错误49出现了。
我尝试了以下内容:
我做错了什么?
答案 0 :(得分:0)
我很惊讶“来自问题标题的呼叫会议”和来自 C#代码的CallingConvention
没有响铃(虽然我不统治在 MS 方面发出误导性错误消息。)
调用约定就像执行子例程时的协议,在:
之间void
))main
)
并确定:
由于#1。,2方(被叫方 / 来电)与同步>非常重要关于调用约定,否则它们会在彼此的脚趾上设置,并且堆栈最终会被破坏。 “ Bad DLL Calling Convention ”就是指这一点:2是不同步。
__stdcall
和__cdecl
之间的差异,并注意它们适用于 32位( x86 )架构。 AFAIK (也由错误备份), Excel 可执行文件(整个 MSOffice )为32位DllExport
):
您将此字段设置为其中一个CallingConvention枚举成员。 CallingConvention字段的默认值为Winapi,而默认值为StdCall约定。
我拿了你的代码,并用它玩了一点。
code.cs :
using System;
using System.Runtime.InteropServices;
using RGiesecke.DllExport;
namespace RSExternalInterface
{
public class RSExternalInterface
{
[DllExport("add")]
public static int TestExport(int left, int right)
{
int ret = left + right;
String s = String.Format("C# Func - add: {0} + {1} = {2}", left, right, ret);
Console.WriteLine(s);
return ret;
}
[DllExport("dbl", CallingConvention = CallingConvention.Winapi)]
public static int TestExport1(int value)
{
int ret = value * 2;
String s = String.Format("C# Func - dbl: {0} * 2 = {1}", value, ret);
Console.WriteLine(s);
return ret;
}
[DllExport("none", CallingConvention = CallingConvention.StdCall)]
public static void TestExport2(int value)
{
String s = String.Format("C# Func - none: {0}", value);
Console.WriteLine(s);
}
}
}
main.vb :
Module main
Declare Function add Lib "CsDll.dll" (ByVal Left As Integer, ByVal Right As Integer) As Integer
Declare Function dbl Lib "CsDll.dll" (ByVal Value As Integer) As Integer
Declare Sub none Lib "CsDll.dll" (ByVal Value As Integer)
Sub Main()
Console.WriteLine("64 bit OS: {0}{1}64 bit process: {2}{1}", Environment.Is64BitOperatingSystem, Environment.NewLine, Environment.Is64BitProcess)
Dim i As Integer
none(-7659)
i = dbl(78)
i = add(22, -13)
End Sub
End Module
备注强>:
- 您必须将平台目标设置为x86,ia64或x64。 AnyCPU程序集无法导出函数。
CallingConvention.Cdecl
),只有在设置为 x86 后才能重现问题输出( VStudio 2015(社区)):
64 bit OS: True 64 bit process: False C# Func - none: -7659 C# Func - dbl: 78 * 2 = 156 C# Func - add: 22 + -13 = 9
这是一个(古老的)网址,它也提到了您的错误:[MSDN]: Bad DLL calling convention (Error 49)