我正在从VBA工作到.NET。 我有一个使用CLI和stdcall的接口的工作版本
我正在尝试删除对C ++ 2015运行时产生的依赖关系,看起来我可以使用UnmanagedExports来完成它。
但我有几个问题。
在任何一种情况下,我是否必须进行任何字符串/字符串长度管理?
我目前在“int”中传递了几个回调。从我在其他地方看到的一个例子来看,它看起来像在C#端,使用这个,我应该能够用Func替换那些参数,例如函数A(p1作为String,p2作为Long,p3作为String)作为Long
非常感谢任何建议。
答案 0 :(得分:0)
你需要StrPtr的组合,可能是Access端的StrConv和.NET端的IntPtr:
'VBA7
Private Declare PtrSafe Function Command Lib "External.dll" (ByVal CommandName As String, ByVal Result As LongPtr, ByRef ResultLength As Long) As Long
'VBA pre7
Private Declare Function Command Lib "External.dll" (ByVal CommandName As String, ByVal Result As Long, ByRef ResultLength As Long) As Long
'Example to use.
'Result will be up to "i" characters - no new string involved
Dim i As Long, x As Long, strResult As String
i = 100
strResult = Space(i)
x = Command(CommandName, Arguments, StrPtr(strResult), i)
如果您使用StrConv,则字符串类型取决于您。如果不这样做,指针将指向Unicode数组。
C#方:
[DllExport("Command", CallingConvention.StdCall)]
public static int Command(string commandName, string arguments, IntPtr result, out /*or ref*/ int resultLength)
{
string inputStr = Marshal.PtrToStringUni(result); //Unicode
resultLength = inputStr.Length;
int x = MainFunc.Command(commandName, arguments, ref inputStr);
if(null == inputStr)
{
inputStr = "";
}
if(inputStr.Length > resultLength)
{
inputStr = inputStr.Substring(0, resultLength);
}
byte[] outputBytes = Encoding.Unicode.GetBytes(inputStr);
Marshal.Copy(outputBytes, 0, result, outputBytes.Length);
resultLength = inputStr.Length;
return x;
}