将本机字符串类型从CLI传递到本机,然后再传回

时间:2014-03-29 05:21:52

标签: c++ com interop c++-cli

我正在尝试围绕一些与COM相关的低级调用编写CLI包装器。我需要做的其中一项操作是从PROPVARIANT获取特定值,即:

pwszPropName = varPropNames.calpwstr.pElems[dwPropIndex];

其中pwszPropName被记录为LPWSTR类型,dwPropIndex是用户传递给函数的DWORD值。

我的本​​机函数定义如下:

HRESULT CMetadataEditor::GetPropertyNameByID(DWORD ID, wchar_t *PropertyName)

我想通过pwszPropName返回*PropertyName的值。

wchar_t*类型是否是执行此操作的最佳方式,我是否需要在CLI中固定*PropertyName以确保它不会在内存中移动?在将*PropertyName传递给本机代码(缓冲区)之前,是否需要定义wchar_t*的长度?

如果LPWSTR是传递给本机函数的正确变量类型,那么whar_t*System::String的正确转换是什么,以及如何将该值转换为{{ 1}}?

在过去的几天里,我尝试了许多不同的技术,似乎无法做到正确。


------------ ------------ UPDATE

这是我的完整代码。首先,CLI:

String^ MetadataEditor::GetPropertyNameByID(unsigned int ID)
{
    LPWSTR mPropertyName = L"String from CLI";

    m_pCEditor->GetPropertyNameByID(ID, mPropertyName);

    //Convert return back to System::String
    String^ CLIString = gcnew String(mPropertyName);
    return CLIString;
}

原生代码:

HRESULT CMetadataEditor::GetPropertyNameByID(DWORD ID, LPWSTR PropertyName)
{
    HRESULT hr = S_OK;
    LPWSTR myPropName;

    PROPVARIANT varNames;
    PropVariantInit(&varNames);

    hr = m_pMetadata->GetAllPropertyNames(&varNames);
    if(hr != S_OK)
    {
        PropVariantClear(&varNames);
        return hr;
    }

    myPropName = varNames.calpwstr.pElems[ID];
    PropertyName = myPropName;
    PropVariantClear(&varNames);
    return hr;
}

似乎值(myPropName)未正确设置和/或维持回CLI函数,因为CLI在调用本机函数之前返回mPropertyName上设置的值。我不确定为什么或如何解决这个问题。


UPDATE !!!!

我怀疑我的问题与超出范围的变量有关。所以我改变了C ++函数定义如下:

LPWSTR GetPropertyNameByID(DWORD ID, HRESULT ErrorCode);  

在调整CLI之后,我现在得到一个返回的值,但第一个字符不正确,实际上每个调用都可能不同。我尝试在本地类中使用ZeroMemory(),然后将PROPVARIANT的输出分配给变量(ZeroMemory(&myPropName, sizeof(myPropName +1));,但仍然没有运气。

1 个答案:

答案 0 :(得分:0)

您可以通过以下方式设计非托管功能:

HRESULT CMetadataEditor::GetPropertyNameByID(DWORD ID, LPWSTR PropertyName, size_t size)
{
    ....
    wcscpy(PropertyName, varNames.calpwstr.pElems[ID]);  // or wcsncpy
    ...
}

PropertyName是调用者分配的缓冲区,size是其大小。在函数wcscpywcsncpy内,字符串varNames.calpwstr.pElems[ID]PropertyName。客户代码:

WCHAR mPropertyName[100];
m_pCEditor->GetPropertyNameByID(ID, mPropertyName, sizeof(mPropertyName)/sizeof(mPropertyName[0]));

例如,考虑如何实现GetComputerName API,并执行相同的