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# - 在多个用户控件之间共享属性

c++ - 从 map 读取时出现 "Invalid initialization"错误

c++ - 如何在 C++ 中保存输入字符串?

c++ - 抽象基类中初始化const成员变量的常用解决方案

c++ bulid消息显示引用参数,而我按值传递参数

c# - FXCop 违规 CA1716 标识符ShouldNotMatchKeyword

c# - 体系结构帮助(WCF 与否)

c++ - 默认仅适用于 8 和 9。之后它使用第一个数字并将其视为 1,2,3

c# - 通过 StructureMap 定义 'HttpClient' 单例导致运行时未配置 'HttpMessageHandler' 的错误

c# - 如何验证 RemoteCertificateValidationCallback 中的链?