Robert Giesecke的Unmanaged Exports - OUT字符串

时间:2018-04-22 21:57:58

标签: c# unmanagedexports

我正在从VBA工作到.NET。 我有一个使用CLI和stdcall的接口的工作版本

我正在尝试删除对C ++ 2015运行时产生的依赖关系,看起来我可以使用UnmanagedExports来完成它。

但我有几个问题。

  1. 我可以只使用“ref string”作为参数并使其有效吗?
  2. 如果是这样,我可以用“out string”替换它吗?
  3. 在任何一种情况下,我是否必须进行任何字符串/字符串长度管理?

  4. 我目前在“int”中传递了几个回调。从我在其他地方看到的一个例子来看,它看起来像在C#端,使用这个,我应该能够用Func替换那些参数,例如函数A(p1作为String,p2作为Long,p3作为String)作为Long

  5. 非常感谢任何建议。

1 个答案:

答案 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;
    }