C# 中的 PInvoke DLL

2023-11-29

我想将一个结构传递给 C 函数,并编写以下代码。

当我运行它时,第一个函数 -Foo1正在工作,然后起作用Foo出现异常。你能帮我理解问题是什么吗?...

C代码:

typedef struct 
{
    int Size; 
    //char *Array;
}TTest;

__declspec(dllexport) void Foo(void  *Test);
__declspec(dllexport) int  Foo1();

void Foo(void  *Test)
{
    TTest *X = (TTest *)Test;
    int i = X->Size;
    /*for(int i=0;i<Test->Size;Test++)
    {
        Test->Array[i] = 127;
    }*/
}

int Foo1()
{
    return 10;
}

C# 代码:

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    [StructLayout(LayoutKind.Sequential)]
    public class TTest 
    {
        public int Size; 
    }

    class Program
    {
        [DllImport(@"C:\.net course\unmanaged1\unmanaged3\Debug\unmanaged3.dll", CharSet = CharSet.Auto)]
        public static extern void Foo(
            [MarshalAs(UnmanagedType.LPStruct)]
            TTest lplf   // characteristics
        );

        [DllImport(@"C:\.net course\unmanaged1\unmanaged3\Debug\unmanaged3.dll", CharSet = CharSet.Auto)]
        public static extern int Foo1();

        static void Main(string[] args)
        {
            TTest Test = new TTest();
            Test.Size = 25;

            int XX = Program.Foo1();
            Program.Foo(Test);
        }
    }
}

致投反对票的人:这个答案解决了两个问题:调用约定/调用约定的直接问题MarhsalAs属性,以及他很快就会发现的问题TTest如果他接受我的转向建议,参数将不起作用TTest到一个结构体中。

您的本机代码要求void*,在 C# 中是IntPtr。首先你应该定义TTest作为结构而不是类。其次,你应该改变声明Foo to:

[DllImport(@"C:\.net course\unmanaged1\unmanaged3\Debug\unmanaged3.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern void Foo(IntPtr lplf);

第三,你应该固定TTest使用fixed关键字并将其指针传递给Foo。如果您使用的是类,则可以使用Marhsal.StructureToPtr得到一个IntPtr从你的TTest.

这在两侧提供了相同的功能,可以传入指向任何类型的指针。您还可以使用要使用的所有类类型编写重载,因为它们都等同于void*在本机方面。对于结构体,您的参数将前面加上一个ref.

我很好奇的是为什么你的本机代码想要一个void*代替TTest*当您在非托管代码中执行的第一件事被转换为TTest*。如果您将参数切换为TTest*,那么提供相同的功能就变得更简单。你的声明将变成:

[DllImport(@"C:\.net course\unmanaged1\unmanaged3\Debug\unmanaged3.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern void Foo(ref TTest lplf);

你可以将该函数称为Program.Foo(ref Test);

如果您正在使用该类,则ref不是必需的,因为类是引用类型。

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

C# 中的 PInvoke DLL 的相关文章

随机推荐

  • 如何在Android上提供像按钮一样的imageview点击效果?

    我的 Android 应用程序中有 imageview 我将其用作带有给定 onClick 事件的按钮 但正如您可能猜到的那样 单击时它不会为 imageview 提供可点击的效果 我怎样才能做到这一点 您可以使用如下所示的方法对单个图像执
  • Solr 配置,加密数据配置文件

    如何在这里加密数据配置部分
  • HTML 电子邮件设计有哪些指南? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 您可以为电子邮件中的丰富 HTML 格式提供哪些指导方针 同时在许多客户端和基于 Web 的电子邮件界面中保持良好的视觉稳定性 Stack Overflow 上一个问题的不相关答
  • 如何将日期时间/时间戳从一个时区转换为另一个时区?

    具体来说 给定我的服务器的时区 系统时间角度 和时区输入 我如何计算系统时间 就好像它处于新时区一样 无论夏令时等 import datetime current time datetime datetime now system time
  • 将 UISearchBar 作为子视图添加到 tableView 标头中

    我正在尝试添加自定义标头UITableView 有一些按钮和一个UISearchBar 问题是 当我尝试使用 searchBar 时 我收到一条消息 setting the first responder view of the table
  • python 3.5更新sqlite3版本

    我已经在 Windows 机器上安装了 python 3 5 3 我通过命令 sqlite3 sqlite version 检查 SQLite 版本 它是版本3 8 11 我的问题是如何将 SQLite 版本更新到 3 26 我不确定是否有
  • 向所有请求添加Where条件EF6

    我的大部分实体 并非全部 有两个属性称为CompanyId and Deleted 如何为所有选择请求自动插入这两个属性 而不是在整个应用程序中的每个查询上手动设置 Example db MyEntity Where me gt me Id
  • Codeigniter/PHP:将数据库查询格式化为数组

    this gt db gt select id user id gt from be users gt where id user id data user individual this gt db gt get 如果这是我的数据库查询
  • REGEXP 与 PDO Mysql

    我正在尝试在 PDO Mysql 中使用 REGEX 但出现问题 function artist list artist global DBH STH DBH gt prepare SELECT songs image artist alb
  • java、反射、内部类、

    您好 我想使用反射获取内部类的对象 但我在其中遇到了一些错误 代码是 package reflaction public class MyReflection public static void main String args thro
  • 遍历 jquery 中的嵌套表单元素

    很抱歉 如果这已经发布了 我一直在寻找无济于事 我只是想知道如何在 jquery 中循环嵌套表单 元素 元素不仅是像输入标签这样的严格表单元素 而且还有其他 html 元素 目前我有这段代码可以做到这一点 arguments i formi
  • Haskell 声明中的感叹号是什么意思?

    当我尝试使用真实的项目来驱动 Haskell 时 我遇到了以下定义 我不明白每个参数前面的感叹号是什么意思 我的书上似乎没有提到它 data MidiMessage MidiMessage Int MidiMessage 这是一个严格的声明
  • 检测 AJAX 何时更改 Web 浏览器中 DIV 中的 HTML

    通过 Web 浏览器加载页面并单击触发 AJAX 脚本的链接后 我需要检测 AJAX java 脚本何时完成将 HTML 更改加载到 div 中 由于运行 AJAX 脚本时不会触发 DocumentCompleted 事件 因此我不知道它何
  • 如何解码这段 PHP 代码?

    我想解码这段代码 我不知道它是什么 只知道它是某种代码 有人能帮助我吗
  • 如何在 EditText 上默认使用数字键盘而不强制输入数字? [复制]

    这个问题在这里已经有答案了 这个问题已经在网上其他地方询问过了 没有结果 Android 有没有办法在聚焦时显示数字软键盘EditText 但仍然允许输入任何文本 我想让用户输入数量 例如 1 kg 2 L 所以只需设置inputType
  • Oracle数据库搜索所有表中的字符串,返回行数据[重复]

    这个问题在这里已经有答案了 我需要在 Oracle 数据库中的所有表中搜索特定字符串 并返回找到该字符串的所有记录 我正在使用 SQL Developer 网上发布了几个非常有用的脚本和存储过程 它们提供了一种搜索整个数据库的方法 并且它们
  • 我可以按任意顺序将中间件应用到应用程序吗?

    在 C ASP NET 中 中间件应用程序的顺序重要吗 以下2个代码片段 public class Startup public void Configure IApplicationBuilder app IHostingEnvironm
  • 删除浏览器默认样式

    有没有办法或者声明如XHTML or HTML4这会删除元素上的默认 CSS 样式吗 Doctype 不用于样式化 有两种重要的方法可以删除所有样式并统一默认外观 标准化 csshttps necolas github io normali
  • C++ 中整数向量的序列化/反序列化

    待完成任务 我正在尝试将整数向量序列化为字符串 以便可以将其存储到文件中 使用的方法是将整数逐字节复制到缓冲区中 为此 我使用了 std copy n 函数 为了反序列化 我反向做了同样的事情 即从缓冲区逐字节复制到整数中 并将这些整数附加
  • C# 中的 PInvoke DLL

    我想将一个结构传递给 C 函数 并编写以下代码 当我运行它时 第一个函数 Foo1正在工作 然后起作用Foo出现异常 你能帮我理解问题是什么吗 C代码 typedef struct int Size char Array TTest dec