首页 \ 问答 \ 使用pInvoke将C样式的LPWSTR数组编组到托管字符串[](Marshalling C-style array of LPWSTR to managed string[] using pInvoke)

使用pInvoke将C样式的LPWSTR数组编组到托管字符串[](Marshalling C-style array of LPWSTR to managed string[] using pInvoke)

我想调用一个非托管方法来分配内存,创建一个LPWSTR数组,并将其返回给托管代码。 我想避免输入/输出参数和编写代码来尽可能地管理内存和变量范围,所以我决定依赖于使用CoTaskMemAlloc并让marshaller在我之后自动清理。

这就是我所拥有的(MSDN上的ap / invoke教程方法的修改版本):

extern "C" DLL1_API LPWSTR *TestArrayOfStrings(_In_ int count)
{
    STRSAFE_LPWSTR temp = NULL;
    wchar_t * ppStrArray[10] = { NULL };
    const size_t alloc_size = sizeof(wchar_t *) * 10;

    for (int i = 0; i < 10; i++)
    {

        temp = (STRSAFE_LPWSTR)CoTaskMemAlloc(alloc_size);

        if (i % 2 == 0)
            StringCchCopy(temp, alloc_size, L"0123456789");
        else
            StringCchCopy(temp, alloc_size, L"9876543210");

        CoTaskMemFree(ppStrArray[i]);
        ppStrArray[i] = temp;
    }
    count = 10;

    return ppStrArray;
}

在管理方面:

[DllImport("Dll1.Windows.dll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0, ArraySubType = UnmanagedType.LPWStr)]
public static extern string[] TestArrayOfStrings(out int count);

正如你所看到的,我已经尝试使用其他属性但是marshaller似乎并不喜欢它 - 我一直得到“无法编组'返回值':无效的托管/非托管类型组合。” 我试图保持打字作为LPWSTR的数组,并希望避免SAFEARRAY ,其编组已被标记为过时。


I'd like to call an unmanaged method that allocates memory, creates an array of LPWSTRs, and returns it to managed code. I'd like to avoid in/out parameters and writing code to manage memory and variable scopes as much as possible so I decided I would rely on using CoTaskMemAlloc and let the marshaller automagically clean up after me.

Here's what I have (a modified version of a p/invoke tutorial method on MSDN):

extern "C" DLL1_API LPWSTR *TestArrayOfStrings(_In_ int count)
{
    STRSAFE_LPWSTR temp = NULL;
    wchar_t * ppStrArray[10] = { NULL };
    const size_t alloc_size = sizeof(wchar_t *) * 10;

    for (int i = 0; i < 10; i++)
    {

        temp = (STRSAFE_LPWSTR)CoTaskMemAlloc(alloc_size);

        if (i % 2 == 0)
            StringCchCopy(temp, alloc_size, L"0123456789");
        else
            StringCchCopy(temp, alloc_size, L"9876543210");

        CoTaskMemFree(ppStrArray[i]);
        ppStrArray[i] = temp;
    }
    count = 10;

    return ppStrArray;
}

and on the managed side:

[DllImport("Dll1.Windows.dll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0, ArraySubType = UnmanagedType.LPWStr)]
public static extern string[] TestArrayOfStrings(out int count);

As you can see I've tried to use additional attributes but the marshaller just doesn't seem to like it--I keep getting "Cannot marshal 'return value': Invalid managed/unmanaged type combination." I am trying to maintain typing as an array of LPWSTRs and would like to avoid SAFEARRAY, for which marshalling is marked obsolete.


原文:https://stackoverflow.com/questions/30019488
更新时间:2021-10-06 17:10

最满意答案

我通过使用Parse.Object.saveAll(objects)解决了这个问题。 现在我没有任何问题一举拯救所有的13K记录。 代码如下所示:

makeHttpRequest('GET', endpoint).then( (httpResponse) => {

    const dataArray = httpResponse.body.array;
    const Class = Parse.Object.extend('className');

    const allObjects = _.map(dataArray, (jsonObject) => {

        const object = new Class();
        object.set(IdKey, "" + jsonObject.id);
        object.set(nameKey, jsonObject.name);
        return object;
    });

    return Parse.Object.saveAll(allObjects, {useMasterKey: true});
});

现在一切似乎都很好。


I solved this by using Parse.Object.saveAll(objects). Now I don't have any problem saving all 13k records in one fell swoop. Code looks like this:

makeHttpRequest('GET', endpoint).then( (httpResponse) => {

    const dataArray = httpResponse.body.array;
    const Class = Parse.Object.extend('className');

    const allObjects = _.map(dataArray, (jsonObject) => {

        const object = new Class();
        object.set(IdKey, "" + jsonObject.id);
        object.set(nameKey, jsonObject.name);
        return object;
    });

    return Parse.Object.saveAll(allObjects, {useMasterKey: true});
});

Everything seems to be working fine now.

相关问答

更多
  • 尝试closedXML并注意区别。 https://www.codeproject.com/Tips/1107815/Export-an-Excel-File-using-ClosedXML Try closedXML and notice the difference. https://www.codeproject.com/Tips/1107815/Export-an-Excel-File-using-ClosedXML
  • 使用此代码 Testing Purposes