C# 调用返回结构的 C++ DLL 函数

2024-05-02

我有一个 C++ dll,它定义了一个结构体和一个 dll 调用,如下所示:

typedef const char* FString;

typedef struct {
    FString version;
    FString build_no;
    FString build_type;
    FString build_date;
    FString build_info;
    FString comment;
} FVersionInfo;

extern "C" FAPI_EXPORT FVersionInfo CALLINGCONV fGetVersion(void);

在 C# 方面,我使用动态加载:

    [DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
    static extern int LoadLibrary(
        [MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);

    [DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
    static extern IntPtr GetProcAddress(int hModule,
        [MarshalAs(UnmanagedType.LPStr)] string lpProcName);

    [DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
    static extern bool FreeLibrary(int hModule);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct FVersionInfo
    {
        public string Version;
        public string Build_No;
        public string Build_Type;
        public string Build_Date;
        public string Build_Info;
        public string Comment;
    }

    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)]
    public delegate FVersionInfo fGetVersion();

    public fGetVersion GetVersion;

    FHandle = LoadLibrary(@pName);
    IntPtr intPtr;
    intPtr = GetProcAddress(FHandle, "fGetVersion");
    GetVersion = (fGetVersion)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(fGetVersion));

调用代码应该是:

FVersionInfo version = new FVersionInfo();
version = GetVersion();

我的第一个问题是,在 c# 加载部分调用 Marshal.GetDelegateForFunctionPointer 时,我变成了“System.Runtime.InteropServices.MarshalDirectiveException”。

然后我使用 IntPtr 作为结构返回参数进行了测试,如下所示:

[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public delegate IntPtr fGetVersion();

所以我让 Marshal.GetDelegateForFunctionPointer 工作,但后来我在编组方面遇到了同样的问题:

IntPtr DllValue = new IntPtr();
FVersionInfo version = new FVersionInfo();
DllValue = fGetVersion();
Marshal.PtrToStructure(DllValue, FVersionInfo);

此处,它在使用“托管调试助手‘PInvokeStackImbalance’”调用 fGetVersion() 时崩溃。我认为这意味着堆栈已损坏(不平衡)。

我已经测试了结构定义的许多变体,但没有结果。

任何想法或建议都将受到欢迎!


感谢您的指导,但我找到了一个可行的解决方案:

  1. 我将结构的声明更改为
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct FVersionInfo
{
    public IntPtr Version;
    public IntPtr Build_No;
    public IntPtr Build_Type;
    public IntPtr Build_Date;
    public IntPtr Build_Info;
    public IntPtr Comment;
}
  1. 所以我通过了Marshal.GetDelegateForFunctionPointer没有任何问题。

  2. 我将使用代码更改为:

GF.FVersionInfo vi = new GF.FVersionInfo();
vi = gf.GetVersion();
  1. 之后,我可以访问字符串,例如

字符串 MyVersion = Marshal.PtrToStringAnsi(VersionInfos.Version);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 调用返回结构的 C++ DLL 函数 的相关文章

随机推荐

  • QCalendarWidget - 如何突出显示日期

    我有一个QList
  • 最近用 Java 编写的 FFTW 包装器

    我正在寻找最新版本的最小 Java 包装器FFTW http www fftw org FFTW 网站上列出的包装器要么已过时 jfftw 1 2 zip ftp ftp fftw org pub fftw jfftw 1 2 zip 或包
  • sqlite 无法识别通用列表

    在 Windows 应用商店应用程序项目中 我从 Web 服务获取 JSON 如下所示 http paste2 org jfMJ2AGA http paste2 org jfMJ2AGA 我有这两门课 public class media
  • Java 中的序列化日期

    我通过 Web 服务传递一些对象 其中一些包含 java sql Date 因为 Date 没有空的构造函数 所以它不想被序列化 问题的第一部分很简单 在客户和服务之间传递日期的最佳方式是什么 第二部分有点棘手 一旦我决定如何传递日期 我显
  • 使用 Joda-Time 有什么缺点吗?

    我想说服架构经理包括乔达时间 http www joda org joda time 我们产品中的罐子 您知道使用它有什么缺点吗 我认为 Joda Time 需要不断更新 因为它包含的文件 这是一个缺点 也许我错了 您能否澄清一下这个主题
  • c# http Post 在 webresponse 中没有得到任何内容

    这是我的请求和响应代码 System IO MemoryStream xmlStream null HttpWebRequest HttpReq HttpWebRequest WebRequest Create url xmlStream
  • 使用 bash 脚本迭代目录中的文件

    我想迭代给定目录中的文件 我尝试使用 for 循环进行相同的操作 但是我在这个循环中还有另一个循环 我需要读取多个文件 直到该循环中的条件为真才能一次上传 但是在内部循环中我是由于文件迭代器循环位于内部循环之外 因此只能访问一个文件 是否有
  • 是否可以仅从复制因子为 3 的 Cassandra 集群中的单个节点读取数据?

    我知道 Cassandra 有不同的读取一致性级别 但我还没有看到一种一致性级别允许仅从一个节点按键读取数据 我的意思是 如果我们有一个复制因子为 3 的集群 那么我们在读取时总是会询问所有节点 即使我们选择一致性级别 1 我们也会询问所有
  • Ant javac 任务出错:[javac] 警告:[选项] 引导类路径未与 -source 1.6 一起设置

    我正在尝试运行一个使用的 ant 任务axis2 ant plugin 1 6 0 jar org apache axis2 tool ant AntCodegenTask执行一个WSDL2Java手术 在ant脚本的顶部 我定义了java
  • 在 Common Lisp 中编写 Lambda 表达式

    我目前正在阅读 Paul Graham 的 ANSI Common Lisp 并且有一个关于编写 lambda 表达式的问题 我们是否需要在 lambda 表达式前面加上前缀 如果我在 REPL 中写这样的东西 它会工作得很好 gt lam
  • 如何在 kibana 中自动配置索引模式

    是否可以在 kibana 中自动配置索引模式 要么通过一些设置文件 要么通过rest api 安装后可以手动完成 Kibana 5 x 公开了这样的 API 来管理索引模式 要创建索引模式 可以发出以下命令来 kibana 访问 url 只
  • 使用java将数据插入mySQL表

    I have a predefined table in a mySQL database 我正在努力将从用户输入的数据保存到数据库中 但我似乎无法将任何数据保存在数据库中 使用以下代码 我尝试更新数据库的第一行 ID 1 到 OTHER
  • 确定视口或“标准”浏览器的最佳方法

    所以 现在我们都知道 iOS 移动 Safari 使用视口 Android 浏览器也是如此 而不是 标准 浏览器窗口 这会导致问题overflow hidden and position fixed 不幸的是 iPad 的情况也是如此 我想
  • 如何在 Objective-C 中删除浮点上的尾随零而不进行四舍五入?

    我需要清除浮点数上的尾随零而不进行四舍五入 我只需要显示相关的小数位 例如 如果我有 0 5 我需要它显示 0 5 而不是 0 500000 如果我有 2 58328 我想显示 2 58328 如果我有 3 我想显示 3 而不是 3 000
  • 在 Elasticsearch 中对具有一个值的属性进行多个值查询

    我正在尝试在这个查询的基础上进行一些构建 我正在搜索的索引还有一个带有 id 的 实体 字段 因此 一些记录将具有 实体 16 实体 156 等 具体取决于实体的 ID 我需要以这样的方式扩展此查询 以便可以传递数组或某些值列表 例如 te
  • 删除键空间挂起

    问题 drop keyspace MyKeyspace hangs 环境 这是 virtualbox 中的 Ubuntu 12 04 64 位 运行单个 Cassandra 实例 在开发计算机上 卡桑德拉是 1 1 6 myuser myh
  • 在 .NET 中使用 try-catch 进行流量控制是否“不好”?

    我刚刚在一个项目中发现 try myLabel Text school SchoolName catch myPanel Visible false 我想与开发人员交谈而不是写这个 说会引发空异常 因为school理论上可能为空 而不是my
  • CSS 选择器:id 或类中的第一个 div

    用于选择类中或具有特定 id 的第一个 div 的正确 CSS 选择器是什么 对于父 子元素来说 这似乎要容易得多 但我还没有找到简单元素的任何内容 更新 解决方案 我发现的最干净 最兼容的解决方案是 class class 它选择前一个类
  • 如何在不使用完整备份的情况下使用生产数据刷新 SQL Server 测试实例

    我有两台 MS SQL 2005 服务器 一台用于生产 一台用于测试 并且两台服务器的恢复模型均为 完整 我将生产数据库的备份恢复到测试服务器 然后让用户进行更改 我希望能够 回滚对测试 SQL 服务器所做的所有更改 应用自测试服务器最初恢
  • C# 调用返回结构的 C++ DLL 函数

    我有一个 C dll 它定义了一个结构体和一个 dll 调用 如下所示 typedef const char FString typedef struct FString version FString build no FString b