在 C# 中将 ref IntPtr 编组到 BSTR *

发布于 2024-10-02 08:34:28 字数 1600 浏览 8 评论 0原文

我正在尝试调用一个函数,该函数为字符串分配内存,然后对字符串执行某些操作。下面是说明该问题的基本示例:

C++:

    STDMETHODIMP CFunctionsCollection::Function2 (  
        BSTR leftString, BSTR rightString, BSTR * conString
    )
{
    int leftLen = lstrlen(leftString);
    int rightLen = lstrlen(rightString);

    *conString = new TCHAR[leftLen+rightLen+1];

    for (int i=0 ; i<leftLen ; ++i)
        (*conString)[i] = leftString[i];
    for (int i=0 ; i<rightLen ; ++i)
        (*conString)[leftLen+i] = rightString[i];
    (*conString)[leftLen+rightLen] = 0;

    return S_OK;
}

来自 C++ 程序的以下调用工作正常:

BSTR leftString = SysAllocString(L"Left String");
BSTR rightString = SysAllocString(L"Right String");
BSTR conString;
hr = pFunctionsCollection->Function2 ( leftString, rightString, & conString);

C# 声明:

Int32 Function2([In, MarshalAs(UnmanagedType.BStr)] String leftString,
                [In, MarshalAs(UnmanagedType.BStr)] String rightString,
                [In, Out] ref IntPtr conStr);

C# 调用:

try
{
    String leftString = "Left String"; 
    String rightString = "Right String";
    IntPtr outStr = IntPtr.Zero;
    pFunctionsCollection.Function2(leftString, rightString, ref outStr);
    String outString = Marshal.PtrToStringUni(outStr);
    Console.WriteLine("Out String = {0}", outString);
}
catch (Exception e)
{
    Console.WriteLine("Call to Function2 failed with {0}", e.Message);
}

程序失败,

调用 Function2 失败,内存不足,无法继续执行程序。

有谁知道如何从 C# 进行这样的调用?

I am trying to call a function which allocates memory for the string and then does something with the string. Here is the basic example which illustrates the problem:

C++:

    STDMETHODIMP CFunctionsCollection::Function2 (  
        BSTR leftString, BSTR rightString, BSTR * conString
    )
{
    int leftLen = lstrlen(leftString);
    int rightLen = lstrlen(rightString);

    *conString = new TCHAR[leftLen+rightLen+1];

    for (int i=0 ; i<leftLen ; ++i)
        (*conString)[i] = leftString[i];
    for (int i=0 ; i<rightLen ; ++i)
        (*conString)[leftLen+i] = rightString[i];
    (*conString)[leftLen+rightLen] = 0;

    return S_OK;
}

The following call from C++ program works just fine:

BSTR leftString = SysAllocString(L"Left String");
BSTR rightString = SysAllocString(L"Right String");
BSTR conString;
hr = pFunctionsCollection->Function2 ( leftString, rightString, & conString);

C# declaration:

Int32 Function2([In, MarshalAs(UnmanagedType.BStr)] String leftString,
                [In, MarshalAs(UnmanagedType.BStr)] String rightString,
                [In, Out] ref IntPtr conStr);

C# call:

try
{
    String leftString = "Left String"; 
    String rightString = "Right String";
    IntPtr outStr = IntPtr.Zero;
    pFunctionsCollection.Function2(leftString, rightString, ref outStr);
    String outString = Marshal.PtrToStringUni(outStr);
    Console.WriteLine("Out String = {0}", outString);
}
catch (Exception e)
{
    Console.WriteLine("Call to Function2 failed with {0}", e.Message);
}

The program fails with

Call to Function2 failed with Insufficient memory to continue the execution of the program.

Does anyone knows how to make such a calls from C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

负佳期 2024-10-09 08:34:28

conString 是一个 BSTR,并且必须如此对待。请参阅 http://msdn.microsoft.com/en-us/library/ms221069。 aspx

  1. 您应该使用 SysStringLen 来获取 BSTR 的长度
  2. C# 中的最后一个参数应该是编组为 BSTR 的输出字符串

    [In, Out, MarshalAs(UnmanagedType.BStr)] out string conStr

  3. 您需要使用 SysAllocString 或 SysAllocStringLen 为 conStr 分配内存

  4. List item

不能使用 'new 分配内存'并将其转换为 BSTR。 BSTR 对内存管理和布局有您无法满足的特定要求。您必须始终遵守这些约定。互操作失败,因为它期望您遵循 BSTR 约定,但您没有遵循。

conString is a BSTR, and must be treated as such. See http://msdn.microsoft.com/en-us/library/ms221069.aspx

  1. You should use SysStringLen to get the length of the BSTRs
  2. You last parameter in C# should be an out string marshalled as a BSTR

    [In, Out, MarshalAs(UnmanagedType.BStr)] out string conStr

  3. You need to allocate the memory for conStr with SysAllocString or SysAllocStringLen

  4. List item

You cannot allocate memory using 'new' and cast it to a BSTR. BSTR's have specific requirements for memory management and layout that you are not satisfying. You must follow these conventions always. The interop fails because it expects you are following the conventions for BSTRs, but you are not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文