【问题标题】:How to get array of strings from DllImport如何从 DllImport 获取字符串数组
【发布时间】:2021-09-02 00:20:15
【问题描述】:

我试图从 dll 中获取字符串数组。

这是这个 dll 函数的文档。

Request_the_Value_of_ICT_multi_Currency_Bill_Validator()
(a)Input
1. strCurrecy: AnsiString
(b)Return:pData: AnsiString*
pData[0] Value1
pData[1] Value2
...
pData[19] Value3
(c)Example:
AnsiString *pData = 
Request_the_Value_of_ICT_multi_Currency_Bill_Validator("AUD");

我在下面尝试了这段代码,返回的是一些非英语语言

IntPtr pData = Request_the_Value_of_ICT_multi_Currency_Bill_Validator("AUD");
string stringB = Marshal.PtrToStringAnsi(pData);

string stringA = Marshal.PtrToStringUni(pData);

这是 dll

[DllImport("PS3_DLL.dll", EntryPoint = "Request_the_Value_of_ICT_multi_Currency_Bill_Validator", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr Request_the_Value_of_ICT_multi_Currency_Bill_Validator(string strCurrency);

这是我反汇编dll得到的功能。我真的不知道这是什么意思

更新:我终于找到了正确的代码!

 IntPtr pData = ictdll.Request_the_Country_code_of_ICT_multi_Currency_BA();

        IntPtr[] pGetData = new IntPtr[9];
        Marshal.Copy(pData, pGetData, 0, pGetData.Length);

        string[] currency = new string[9];

        for (int i = 0; i < 9; i++)
        {
            currency[i] = Marshal.PtrToStringAnsi(pGetData[i]);
        }

【问题讨论】:

  • 我们不知道DLL的接口是什么。
  • @DavidHeffernan 这也是我的问题之一,因为我没有 dll 接口。
  • 我们看不到它,它不在问题中,所以没有人可以回答这个问题。也许该链接中有某些内容,但谁愿意关注非站点链接?如果您有额外的信息,请在此处提供,而不是在站外链接中。
  • @DavidHeffernan 我已经更新了我的问题。我复制了文档的内容并将其包含在我上面的问题中。
  • 这并没有真正详细地指定接口

标签: c# dll dllimport kiosk


【解决方案1】:

您提供的文档清楚地写着Ansi。另外,这看起来是一个字符串指针的数组,所以你需要编组整个数组。

目前尚不清楚谁应该释放所有这些内存,您可能需要对此进行调查。

[DllImport("PS3_DLL.dll", CharSet = CharSet.Ansi,
    CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr[] Request_the_Value_of_ICT_multi_Currency_Bill_Validator
    (string strCurrency);
var arrPtr = Request_the_Value_of_ICT_multi_Currency_Bill_Validator
    (yourCurrency);

arrayOfStrings = arrPtr.Select(ptr =>
    Marshal.PtrToStringAnsi(ptr)).ToArray()

我建议您检查调用约定是否正确。 Windows API 使用StdCall,但大多数C 库使用CDecl

【讨论】:

  • 真的吗? string[] 将如何编组和处理内存作为返回值?谁分配了什么,在哪里解除分配。但这肯定是不正确的,因为即使 p/invoke 编组器准备好运行它,它也会假设在 COM 堆上分配了任何内存,这似乎有点牵强。基本上这个问题不能按现状回答。信息不足。
  • @Charlieface,感谢您的回答,我已经尝试过了,但 UnmanagedType.ByValArray 中有错误。它说 ByValArray 仅对字段有效。
  • @JomanRey OK 已修改。仍然不清楚谁应该释放内存
  • 那也行不通。这真的不是猜测和猜测的话题。
  • @Charlieface 会更新我的问题,我会提供 dll 功能,但它是用汇编编写的,不知道是否有帮助。
【解决方案2】:

浏览了很多天,我终于找到了正确的代码!

    IntPtr pData = ictdll.Request_the_Country_code_of_ICT_multi_Currency_BA();

    IntPtr[] pGetData = new IntPtr[9];
    Marshal.Copy(pData, pGetData, 0, pGetData.Length);

    string[] currency = new string[9];

    for (int i = 0; i < 9; i++)
    {
        currency[i] = Marshal.PtrToStringAnsi(pGetData[i]);
    }

【讨论】:

    猜你喜欢
    • 2011-05-31
    • 1970-01-01
    • 2015-03-26
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 2021-03-06
    • 2021-05-08
    • 2018-12-21
    相关资源
    最近更新 更多