c# - 我有一个 c++ 代码需要翻译成 c#,几乎完成(我认为)但需要 P/Invoke 的帮助才能使用非托管 dll

标签 c# c++

我在处理需要转换为 c# 的项目(在 c++.net 中)时遇到了困难。该项目使用以非托管 C++ 编写的 API。我有 API 的 .lib、.dll 和 .h,并且想使用 p/invoke 从 .net 内部调用 dll 函数。好的,这是代码: 首先,有这个 C++ 结构

typedef struct {
    struct Item {
        int  condition;
        char name[80];

        Item::Item()
        {
            reset();
        }

        void Item::reset()
        {
            condition = 0;
            memset(name, 0, sizeof(name));
        }
    };

    bool    channel[32];
    int     itemCount;
    Item    item[5];
} TEXTIN_QUERY_CONDITION, *LPTEXTIN_QUERY_CONDITION;

翻译成 c# 会是这样的(我想,如果我错了请纠正我):

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct TEXTIN_QUERY_CONDITION
{
    [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, 
    SizeConst = 32, ArraySubType = System.Runtime.InteropServices.UnmanagedType.Bool)]
    public bool[] channel;
    public int itemCount;
    public ItemClass[] item; //how define the size (5)???
}

我的 ItemClass 看起来像这样:

class ItemClass
{
    public Item item = new Item();

    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, 
    CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
    public struct Item
    {
        public int condition;
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, 
        SizeConst = 80)]
        public string name;
    }

    public ItemClass()
    {
        reset();
    }

    public void reset()
    {
        item.condition = 0;
        item.name = new string('0', 80);
    }
}

在 .h 文件中有这个函数的定义:

bool search_queryTextIn(const LPBYTE condition, bool queryNext);

我认为它可以像这样转换为 c#:

[DllImport("search.dll")]
protected static extern bool search_queryTextIn( 
    [MarshalAs(UnmanagedType.LPArray)] byte[] condition, 
    [MarshalAs(UnmanagedType.I1)] bool queryNext);

然后,在 C++ 代码中,函数是这样调用的:

void queryTextIn(TEXTIN_QUERY_CONDITION& condition, bool queryNext)
{
    _searchCore.queryTextIn(&condition, queryNext);
}

并且 _searchCore.queryTextIn 方法定义如下:

bool SearchSDK_Class::queryTextIn(const LPTEXTIN_QUERY_CONDITION condition, bool queryNext)
{
    return ::search_queryTextIn((LPBYTE)condition, queryNext);
}

调用上面.h中定义的函数。我的主要问题是如何从 c# 调用此函数。首先,我创建了一个 TEXTIN_QUERY_CONDITION 结构的实例,但我不知道如何将指向该结构的指针作为参数传递,以及如何将其转换为字节数组以最终调用该函数......拜托,拜托,是有某种灵魂可以帮助我弄清楚调用非托管函数的最后一点吗?非常感谢。

最佳答案

item 成员不是指针,所以ItemClass 翻译需要是值类型,而不是类。然后使用 MarshalAs 属性并指定 SizeConst 就像您对 channel 所做的那样。或者使用 fixed keyword .

关于c# - 我有一个 c++ 代码需要翻译成 c#,几乎完成(我认为)但需要 P/Invoke 的帮助才能使用非托管 dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3664792/

相关文章:

c# - 显示 GridView 中的行数

c# - 为 Windows 窗体自定义控件定义事件

c# - Windows 任务调度程序 C#

C#:即使在使用 httpclient 发送 CSRF token 后仍获得 403

c++ - C++ 代码中的质因数不适用于所有输入

c++ - 我的转置矩阵代码有什么问题?

c++ - 在嵌入式 x86 程序集中添加数组?

c# - 在 IIS 上工作时 System.Diagnostic.Trace.CorrelationManager.ActivityId 生成为空

c++ - 我没有遵循标准吗?

c++ - 在我的程序中更改共享库中定义的变量不会从共享库中反射(reflect)出来