编组对char **数组的引用

时间:2015-03-20 12:23:55

标签: dll pinvoke marshalling

我无法通过引用编组一组char *。数据在C ++非托管端正确填写。但是当它通过引用返回到托管端时,我最终会得到一个指向第一个数组元素的指针。

//The function in C++
extern "C" DATAACCESSLAYERDLL_API void  __stdcall DB_SchemaField_GetKeyValues(Schema::TSchemaFieldHandle hField, const char** &keys, const char ** &values)
{
    Schema::CSchemaField *pField = CDataObjectFactory::GetObjectTpl<Schema::CSchemaField>(hField);
    if (!pField) return;
    Schema::TSchemaKeyValuePair::iterator itor = pField->GetKeyValues().begin();

    int index = 0;
    for (itor; itor != pField->GetKeyValues().end(); ++itor)
    {
        keys[index] = (*itor).first.c_str();
        values[index] = (*itor).second.c_str();
        index++;
    }

    return;
}

pInvoke声明

[System.Security.SuppressUnmanagedCodeSecurity()]
[DllImport("DataCore.dll")]
static private extern void DB_SchemaField_GetKeyValues(Int64 pField, 
    [In, Out] ref IntPtr[] keys, [In, Out] ref IntPtr[] values);

最后......编组的代码

    int keyValueCount = DB_SchemaField_GetKeyValuesCount(GetHandle());
    if (keyValueCount > 0)
    {
        IntPtr[] KeysPtr = new IntPtr[keyValueCount];
        IntPtr[] ValuesPtr = new IntPtr[keyValueCount];

        DB_SchemaField_GetKeyValues(GetHandle(), ref KeysPtr, ref ValuesPtr);
        for (int i = 0; i < keyValueCount; i++)
        {
            string key = Marshal.PtrToStringAnsi(KeysPtr[i]);
            string value = Marshal.PtrToStringAnsi(ValuesPtr[i]);
            if (!String.IsNullOrEmpty(key))
            {
                KeyValues.Add(key, value);
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

通过引用传递两个const char*数组是错误的。对于编组来说,这是间接的一个层面。您需要以下内容:

<强> C ++

extern "C" DATAACCESSLAYERDLL_API void  __stdcall DB_SchemaField_GetKeyValues(
    Schema::TSchemaFieldHandle hField, const char** keys, const char ** values)

<强> C#

[System.Security.SuppressUnmanagedCodeSecurity()]
[DllImport("DataCore.dll")]
static private extern void DB_SchemaField_GetKeyValues(Int64 pField, 
    [Out] IntPtr[] keys, [Out] IntPtr[] values);

您最好确保使用立即返回的指针,因为c_str()返回的C字符串仅在下一次修改std::string对象之前有效。