加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

将一个字符串数组从C#传递给C dll然后再传回

发布时间:2020-12-15 05:39:26 所属栏目:百科 来源:网络整理
导读:我已经浏览了googleverse和堆栈溢出,并且已经看到了几个类似的问题,但我找到的答案都没有为我工作.我是新会员,所以我不允许在别人的问题上评论答案,要求澄清,所以我不得不求助于我自己. 好的,我试图将一个字符串数组从C#应用程序传递给C dll,然后在另一个C#
我已经浏览了googleverse和堆栈溢出,并且已经看到了几个类似的问题,但我找到的答案都没有为我工作.我是新会员,所以我不允许在别人的问题上评论答案,要求澄清,所以我不得不求助于我自己.

好的,我试图将一个字符串数组从C#应用程序传递给C dll,然后在另一个C#应用程序中获取该信息.我相信我正确地传递给C但是我无法从dll中获得正确的字符串.

我这样传递给C:

[DllImport("KinectPlugins.dll",CallingConvention = CallingConvention.Cdecl)]
    private static extern void SetGrammarData(string[] strArr,int size);


    public void SetGrammar(string[] strArr)
    {
        SetGrammarData(strArr,strArr.Length);
    }

我的C代码看起来像这样:

#define EXPORT_API __declspec(dllexport)
#pragma data_seg(".SHARED")
    char** grammarData;
    int grammarDataLength = 0;
#pragma data_seg()
#pragma comment(linker,"/section:.SHARED,RWS")

EXPORT_API void SetGrammarData(char** strArr,int size)
{
    grammarData = strArr;
    grammarDataLength = size;
}

EXPORT_API int GetGrammarDataLength()
{
    return grammarDataLength;
}
EXPORT_API char** GetGrammarData()
{
    return grammarData;
}

我在其他C#应用程序中抓取信息的代码如下所示:

[DllImport("KinectPlugins.dll")]
private static extern IntPtr GetGrammarData();
[DllImport("KinectPlugins.dll")]
private static extern int GetGrammarDataLength();

public string[] GetGrammar()
{
    int size = GetGrammarDataLength();
    List<string> list = new List<string>();
    IntPtr ptr = GetGrammarData();
    IntPtr strPtr;
    for (int i = 0; i < size; i++)
    {
        Console.WriteLine("i = " + i);
        strPtr = Marshal.ReadIntPtr(ptr);
        list.Add(Marshal.PtrToStringAnsi(strPtr));
        ptr += Marshal.SizeOf(typeof(IntPtr));
    }
    return list.ToArray();
}

理论上,这应该基于我的研究,因为我已经看到其他几个人使用几乎相同的代码.实际上,我传入的是:

SetGrammar(new string[] { "b","a" });

另一方面回来的是:

stringArray[0] = 
stringArray[1] = H-?l?

如果某些人由于某种原因无法查看它或另一个stringArray [1]等于H,–,一条粗线,l和一个快乐的面部符号.这显然不是我投入的.

有没有人知道我哪里可能出错?很长一段时间以来我一直在反对这个问题,并且真的可以使用一些帮助,因为感觉我在这里错过了一些非常简单的东西.

编辑:
根据antijon的建议,我确实更改了我的SetGrammarData来制作字符串的副本,但我仍然遇到了问题.

新代码:

(inside the data_seg)
wchar_t* grammarData;
(end data_seg)

EXPORT_API void SetGrammarData(wchar_t* strArr,int size)
{
    delete[] grammarData;
    grammarData = new wchar_t[size];
    std::memcpy(grammarData,strArr,sizeof(wchar_t) * size);
    grammarDataLength = size;
}
EXPORT_API wchar_t* GetGrammarData()
{
    return grammarData;
}

现在我最终得到了这个输出:

stringArray[0] = 8
stringArray[1] =

C#代码保持不变.还有什么我需要改变的东西,我失踪了吗?

EDIT2:
刚刚意识到wchar_t就像一个char,而不是一个字符串,不知道为什么我认为它表现得像一个字符串.回到绘图板,需要弄清楚如何最好地复制wchar_t **.不是经验丰富的C,但我不认为有可能得到一个wchar_t *的长度,而不是自己传递它,但我将不得不调查它.

EDIT3:
终于让它正常工作了.

这是我最终得到的:

(inside the data_seg)
std::wstring* grammarData;
(end data_seg)

EXPORT_API void SetGrammarData(wchar_t** strArr,int size)
{
    delete[] grammarData;
    grammarDataLength = size;
    grammarData = new std::wstring[size];
    for(int i = 0; i < size; i++)
    {
        grammarData[i] = std::wstring(strArr[i]);
    }
}

EXPORT_API const wchar_t** GetGrammarData()
{
    const wchar_t** wct = new const wchar_t*[grammarDataLength];
    for(int i = 0;i<grammarDataLength;i++)
    {
        const wchar_t* t = grammarData[i].c_str();
        wct[i] = t;
    }
    return wct;
}

Edit4:
以为我让它正常工作,是不正确的.我正在测试一个exe回传给自己但是当通??过dll到另一个exe时,没有任何东西会通过.我现在有它工作:

(inside the data_seg)
wchar_t grammarData[32][50] = {};
(end data_seg)

EXPORT_API void SetGrammarData(wchar_t** strArr,int size)
{
    grammarDataLength = size;
    for(int i = 0; i < size; i++)
    {
        wcscpy(grammarData[i],strArr[i]);
    }
    grammarDataChanged = 1;
}

EXPORT_API wchar_t** GetGrammarData()
{
    wchar_t** wct = new wchar_t*[grammarDataLength];
    for(int i = 0;i<grammarDataLength;i++)
    {
        wct[i] = grammarData[i];
    }

    grammarDataChanged = 0;
    return wct;
}

解决方法

这里有几个可能的问题:

>默认情况下,.NET将编组为wchar_t,而不是char.您需要使用MarshalAsAttribute标记输入/输出字符串参数以使用char.>如果要保留字符串,则需要在C函数中复制它们.在函数调用SetGrammarData时给你的指针不能保证持久化.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读