添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
首页
学习
活动
专区
工具
TVP
最新优惠活动
发布
精选内容/技术社群/优惠产品, 尽在小程序
立即前往

为什么c#无法从非托管dll获取正确的参数值

C#是一种面向对象的编程语言,它在与非托管代码(如C++)进行交互时,可能会遇到从非托管DLL获取正确参数值的问题。以下是对这个问题的完善且全面的答案:

在C#中,无法直接从非托管DLL获取正确的参数值的原因主要有以下几点:

  1. 数据类型不匹配:非托管DLL中的函数可能使用了与C#不同的数据类型,例如C++中的指针、结构体等。在调用非托管DLL函数时,需要进行数据类型的转换和适配,否则无法正确获取参数值。
  2. 内存管理问题:非托管DLL中的函数可能使用了自己的内存管理方式,而C#使用的是垃圾回收机制。在调用非托管DLL函数时,需要确保内存的正确分配和释放,否则可能导致参数值获取错误。
  3. 调用约定不匹配:非托管DLL中的函数可能使用了与C#不同的调用约定(Calling Convention),例如stdcall、cdecl等。在调用非托管DLL函数时,需要使用正确的调用约定,否则可能导致参数值获取错误。

为了解决从非托管DLL获取正确参数值的问题,可以采取以下方法:

  1. 使用平台调用(Platform Invocation Services,P/Invoke):C#提供了P/Invoke机制,可以通过声明DLLImport特性来引入非托管DLL中的函数,并使用Marshal类进行数据类型转换和内存管理。可以参考微软官方文档中的P/Invoke教程(https://docs.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke)。
  2. 使用COM互操作性(COM Interop):如果非托管DLL是基于COM(Component Object Model)的,可以使用C#的COM互操作性功能进行交互。可以使用Visual Studio自动生成的互操作性代码,或者手动编写互操作性代码。可以参考微软官方文档中的COM互操作性教程(https://docs.microsoft.com/en-us/dotnet/standard/native-interop/com-interop)。
  3. 使用托管C++(Managed C++):如果非托管DLL是使用C++编写的,可以考虑将其转换为托管C++,然后再与C#进行交互。托管C++可以直接调用非托管代码,并提供更好的类型安全性和内存管理。可以参考微软官方文档中的托管C++教程(https://docs.microsoft.com/en-us/cpp/dotnet/dotnet-programming-with-cpp-cli-visual-cpp)。

总结起来,要从非托管DLL获取正确的参数值,需要进行数据类型转换、内存管理、调用约定匹配等操作。通过使用P/Invoke、COM互操作性或托管C++等方法,可以实现C#与非托管DLL的交互,并正确获取参数值。

相关· 内容

.NETC# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法

句柄(可在 dll 入口函数中 获取 );而我们是 托管 代码 dwThreadId 是线程 Id,传入 0 则为全局所有线程,否则传入特定 线程 Id 需要注意 坑 模块句柄传什么?...本文一开始被注释掉 代码中,我使用 Marshal 直接 托管 程序集中 获取 了模块句柄。 这里需要说明, 托管 程序集不能注入到其他进程,因此也不可以挂接钩子。...通过调试也能发现这两个 入口模块是相同 : 至于 为什么 可以用 user32. dll 。...所以更推荐使用前一小节中提供 LoadLibrary 函数来 获取 模块句柄,而不是 获取 当前 托管 模块 句柄。...办法总还是有的: 可以考虑做 托管 dll ,专门用来挂接; 可以考虑使用 SetWinEventHook,这个是不用注入到目标进程 ; 可以考虑使用 System.Windows.Automation

1K 2 0

C# 中DllImport用法汇总

大家在实际工作学习 C# 时候,可能会问: 为什么 我们要为一些已经存在 功能(比如Windows中 一些功能,C++中已经编写好 一些方法)要重新编写代码, C# 有没有方法可以直接都用这些原本已经存在 功能呢...其功能是提供 托管 DLL 导出 函数进行调用所必需 信息。DllImport属性应用于方法,要求最少要提供包含入口点 dll 名称。...这个问题最常出现在使用第三方 托管 DLL 组件 时候,我 也同样是这时出 问题,Asp.Net Team 官方解决方案如下: 首先需要确认你引用了哪些组件,那些是 托管 ,哪些是非 托管 . 托管 很好办,直接被使用 需要引用...实际上,你拷贝到bin没有任何帮助,因为CLR会把文件拷贝到一个临时目录下,然后在那运行web,而CLR只会拷贝 托管 文件,这就是 为什么 我们明明把 托管 dll 放在了bin下却依然提示不能加载模块了。...我们 托管 定义开始: typedef struct _SYSTEM_POWER_STATUS { BYTE  ACLineStatus; BYTE  BatteryFlag

1.9K 1 0
  • 模拟隐蔽操作 - 动态调用(避免 PInvoke 和 API 挂钩)

    使用它,我们展示了如何 内存或磁盘动态调用 托管 代码,同时避免 API 挂钩和可疑导入。...此外,此 API 让您可以轻松地在 C# 内存中调用 托管 代码(传递参数并接收输出),而无需执行一些像自注入 shellcode 这样 变通方法。 我们通过Delegates 魔力实现了这一点。....如果将此与通常在 C# 内存中调用 托管 代码 方式(通过自注入 shellcode)进行比较,这会容易得多! 定义委托 工作方式类似。您可以定义一个类似于定义变量 委托。...DInvoke 库为每个 托管 函数提供了一个 托管 包装函数。包装器通过确保 正确 传递参数并返回 正确 类型 对象来帮助用户。 值得注意 是:PInvoke 比 DInvoke 对数据类型更宽容。...您必须以完全 正确 方式编组数据,确保您传入 数据结构在内存中 格式和布局与 托管 代码所期望 相同。您还必须指定 正确 调用约定。这很烦人。

    2K 0 0

    net开发平台regasm注册,gacutil 工具

    (1).regasm.exe文件是什么 首先regasm.exe工具是用来注册net平台这种 托管 语言编写 dll 类库 ,包括com扩展。 为什么 不是regsvr32 呢?...因为net平台生成 并不是真正 二进制文件, 无法 使用regsvr32 进行注册。... /i D:\wwwroot\ c# \Wpc\Wpc\bin\Debug\Wpc. dll 全局注册需要两步,最后一步操作将你 dll 文件放到全局程序集缓存目录C:\Windows\Microsoft.NET...gacutil.exe文件必须安装Visual Studio ide并且使用ide提供 命令行工具使用 (5).全局注册后想换为 全局注册需要先卸载全局,卸载命令 C:\Windows\Microsoft.NET...(6).低版本 regasm不能注册高net版本 dll (7).一般推荐 全局注册,只要不删除 dll 即可,毕竟gacutil文件官方不提供

    440 0 0

    通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?

    那么在 C# 角度,那些脱离了.NET提供 诸如垃圾回收器这样 环境管制,就是对应 托管 了。 托管 异常 我们编写 程序有的模块是由 托管 代码编写,有的模块则调用了 托管 代码。...,当你打上这行命令并按回车后,必须满足几个条件,1.是.cs后缀 c# 格式文件,2.是 代码语法等检测分析必须 正确 ,3.是 使用 类库必须有出处(引用 dll ),当然 因为我是编译为控制台程序,所以还必须得有个静态... 托管 堆模型 而引用类型相比值类型就有点特殊,newobj创建一个引用类型,因其类型内 引用对象可以指向任何类型,故而 无法 准确得知其固定大小,所以像对于引用类型这种 无法 预知 容易产生内存碎片 动态内存,我们把它放到 托管 堆中存储... 托管 世界 内存不需要我们打理,我们 无法 代码中得知具体 托管 对象 大小,你如果想追求对内存最细微 控制,显然 C# 并不适合你,不过类似于有关内存把控 这部分功能模块,我们可以通过 托管 语言来编写,然后通过...,仅仅是.NET平台上 ,因此它只限制于 托管 代码,我们可以直接调用 托管 代码或进程通信间接调用 托管 代码等多个手段来突破对 托管 代码 操作资源 限制。

    2.7K 6 3

    通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?

    那么在 C# 角度,那些脱离了.NET提供 诸如垃圾回收器这样 环境管制,就是对应 托管 了。... 托管 异常 我们编写 程序有的模块是由 托管 代码编写,有的模块则调用了 托管 代码。...,当你打上这行命令并按回车后,必须满足几个条件,1.是.cs后缀 c# 格式文件,2.是 代码语法等检测分析必须 正确 ,3.是 使用 类库必须有出处(引用 dll ),当然 因为我是编译为控制台程序,所以还必须得有个静态... 托管 世界 内存不需要我们打理,我们 无法 代码中得知具体 托管 对象 大小,你如果想追求对内存最细微 控制,显然 C# 并不适合你,不过类似于有关内存把控 这部分功能模块,我们可以通过 托管 语言来编写,然后通过...,仅仅是.NET平台上 ,因此它只限制于 托管 代码,我们可以直接调用 托管 代码或进程通信间接调用 托管 代码等多个手段来突破对 托管 代码 操作资源 限制。

    4.4K 3 0

    C# 调用C和C++函数 一点区别

    ,const char* outMP3Name); #endif 按照 C# 调用 托管 程序 约定,声明一个对应 C# 函数接口: [DllImport("mp3enc. dll ", CharSet = CharSet.Ansi...U800Test.Form1::mp3_enc” 调用导致堆栈不对称。原因可能是 托管 PInvoke 签名与 托管 目标签名不匹配。...请检查 PInvoke 签名 调用约定和参数与 托管 目标签名是否匹配。...于是将 C# 函数接口改成: [DllImport("mp3enc. dll ", CharSet = CharSet.Unicode)] public static extern int mp3_enc(... 正确 C++ 函数 C# 调用接口应该是这样: [DllImport("mp3enc. dll ", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl

    1.7K 6 0

    托管 C++、C++CLI、CLR

    不过,通过使用特殊 关键字, C# 数据可以被标记为 托管 数据。Visual C++数据在默认情况下是非 托管 数据,即使在使用 /CLR 开关时也不是 托管 。   ...另外,一个 托管 类也完全可以成为 .NET 框架 成员,由此可以带来 好处是,它可以与其他语言编写 正确 地进行相互操作,如 托管 C++类可以 Visual Basic类继承等。...2、 为什么 使用 托管 C++   除了可以充分发挥.NET框架新特性外,使用 托管 C++还有下列好处:   (1) 由于在同一个应用程序中,甚至是同一个文件中,我们可以同时使用 托管 C++和传统 托管 C+...(2) 使用 托管 可以 任何一个.NET框架兼容语言中调用一个C++组件,也可调用 托管 DLL 、其它库以及类等。   (3) 可以直接 托管 代码中访问.NET框架。   ...一个__gc类不能从一个 托管 类中继承,且不能包含 它派生 托管 类。但一个__gc类最多可以从一个 托管 类中继承。   B. 一个__gc类不能定义成一个友元类或包含一个友元成员函数。

    2.8K 4 0

    C++ .NET编程: 托管 C++概述

    默认情况下, C# 、Visual Basic 和 JScript.NET 数据是 托管 数据。不过,通过使用特殊 关键字, C# 数据可以被标记为 托管 数据。...另外,一个 托管 类也完全可以成为 .NET 框架 成员,由此可以带来 好处是,它可以与其他语言编写 正确 地进行相互操作,如 托管 C++类可以 Visual Basic类继承等。...(3) 托管 C++空项目:用来创建一个空 托管 项目,该项目只含有支持 托管 扩展 正确 编译和链接 开关选项。使用它能将一个已有的C++源文件进入到一个 托管 环境中。    ...一个__gc类不能从一个 托管 类中继承,且不能包含 它派生 托管 类。但一个__gc类最多可以从一个 托管 类中继承。    B. 一个__gc类不能定义成一个友元类或包含一个友元成员函数。... 代码中可以看出设置和 获取 属性 成员函数名称中分别使用了set_和get_,这样编译器会自动生成一个伪成员变量Size,这个变量名是set_和get_成员函数后面的名称。

    1.5K 2 0

    红队技巧之F#利用

    援引微软官方 解释: F # 是一种函数编程语言,可方便编写 正确 且可维护 代码。F # 编程主要涉及如何定义自动推断和通用化 类型和函数。...至于 为什么 要学习F#,其实也是跟 C# 道理是一样 ,在某些特殊情况下,我们可以利用F#来达到我们 目的,原常景如下: This customer really locked down their environment...但这并不意味着我们便 无法 在内存中运行我们 F#程序,我们可以使用 托管 代码 方法来运行任意 我们 F#程序。...比较好 demo就是: https://github.com/etormadiv/HostingCLR 也就是用 托管 来加载CLR实现内存加载。...实现过程如下: 1.将CLR加载到进程中:调用CLRCreateInstance函数以 获取 ICLRMetaHost或ICLRMetaHostPolicy接口,调用ICLRMetaHost 方法来 获取 有效

    1.5K 3 0

    2019-3-7-手把手教你PInvoke

    ---- 这个时候你就会接触到一些美妙 dll ,比如user32. dll ,kernal32. dll 当然这些是非 托管 代码,我们在.net中 无法 直接使用,所以我们会需要使用PInvoke进行调用 于是你会使用...DllImport特性标记一个方法,引入 托管 函数 比如 我们希望弹出一个消息框,就会使用下面这个函数,添加DllImport特性,表明 哪个 dll 引入方法 public class Win32 {...; 接着我们 Syntax中找到函数签名 这里比较麻烦 是4个参数 需要转换为对应 托管 类型,有时候还会涉及一些结构体和指针。 这里我们先看一下Parameters ?...最后一个是UINT,我们直接在 c# 中有对应 uint 这么一看是不是就更加能够理解了呢。...实操 再来一个简单 例子,我们期望 获取 HID设备 接口GUID 方法给到你们,是HidD_GetHidGuid 先看requirements.txt,发现 DLL 是Hid. dll ?

    871 3 0

    使用C#+FFmpeg+DirectX+dxva2硬件解码播放h264流

    因此行文看起来会乱一些,如果你看到某处能会心一笑请马上联系我开始摆龙门阵 如果你跟随这篇文章实现了播放器,那你会得到一个高效率,低cpu占用(单路720p视频解码播放占用1%左右cpu),且代码和引用精简(无其他 托管 托管 ...安装好dx sdk后我们得到 c# 托管 引用 dll 第二步是修改ffmpeg源码并编译,我们要修改 源码只有一个文件 十余行,而且是增量修改。...将msys自带link重命名避免冲突 打开msys,查看变量是否 正确 检查变量 正确 性 编译ffmpeg ....进行可能 异常处理(实际上还是推倒重来)   番外篇: C# 对DiretX调用 封装 上文中我们使用DirectX 方式看起来即 COM组件,又 C- DLL P/Invoke,难道DirectX真有 托管 代码...答案是否定 C# dll 当然也是调用系统 d3d9. dll

    3.3K 1 1

    ILRuntime热更新

    项目/教程地址:传送门 IL热更优点: 1、无缝访问 C# 工程 现成代码,无需额外抽象脚本API 2、直接使用VS2015进行开发,ILRuntime 解译引擎支持.Net 4.6编译 DLL 3、执行效率是...除了默认 AppDomain,正在使用 托管 COM接口方法 或 托管 类型方法 宿主还可要求CLR创建额外 AppDomain。AppDomain是为了提供隔离而设计 。...=cc7b13ffcd2ddd51” 引用 解决方案:我 默认工程文件框架为4.6.0,更改到更高 版本再进行编译即可生成 dll 顺利生成 dll 文件 安装调试器 报错:安装 无法 将此扩展安装到所有选定 产品...大规模 数值 计算:如果在热更内需要进行大规模 数值 计算,则可以开启ILRuntime在2.0版中加入 寄存器模式来进行优化 避免使用foreach:尽量避免使用foreach,会不可避免地产生GC。...使用MonoBehaviour->不建议) 09.Reflection(主工程反射 DLL 类型) 热更 DLL 中使用反射跟原生 C# 没有区别 Demo主要介绍主工程反射热更 DLL 类型 void OnHotFixLoaded

    2.3K 3 0

    程序员级别鉴定书(.NET面试问答集锦)

    这里问 是强名称概念。Assembly.Load("foo. dll ")加载程序集 方法是否 正确 ? 强签名 程序集与 强签名 程序集有何不同? DateTime 可以为null吗? 什么是 JIT?...因为同样一个名称 文件可能有不同 版本和区域,此时单独靠文件名称,可能会造成不能确定程序集 正确 性。 Assembly.Load("foo. dll ")加载程序集 方法是否 正确 ?...Finalize只释放 托管 资源; Dispose释放 托管 托管 资源 Finalize和Dispose共享相同 资源释放策略,因此他们之间也是没有冲突 。 Using()模式有用吗?... 为什么 用,或 为什么 不用它? Debug和Release编译产出物不一样,Release下无调试信息,如Assert 无法 使用。对程序运行速度而言,无明显区别。...先调用了this(),即无 构造函数,再调用了自身 构造函数。 因为未对a参数进行处理,故无用。 This是什么?可以在静态方法中调用 this 吗?

    1.8K 7 0

    一文看懂 .NET 异常处理机制、原则以及最佳实践

    StackOverflow 表示栈溢出,这通常说明实现代码 时候写了不 正确 显式或隐式 递归 OutOfMemoryException 表示 托管 堆中已 无法 分出期望 内存空间,或程序已经没有更多内存可用了...AccessViolationException 这说明使用 托管 内存时发生了错误 BadImageFormatException 这说明了加载 dll 并不是期望中 托管 dll TypeLoadException...表示 托管 堆中已 无法 分出期望 内存空间,或程序已经没有更多内存可用了 AccessViolationException 这说明使用 托管 内存时发生了错误 BadImageFormatException...这说明了加载 dll 并不是期望中 托管 dll TypeLoadException 表示类型初始化 时候发生了错误 环境错误: IOException 下 各种子类 Win32Exception 下 各种子类...AccessViolationException 当出现此异常时,说明 托管 内存中发生了错误。如果要解决问题,需要从 托管 代码中着手调查。 这个异常是访问了不允许 内存时引发

    719 4 1

    .NET Core多线程 (1) Thread与Task

    时间和空间角度理解线程 开销 (1)多线程 优点 提高响应能力 main thread:更新UI 东西 work thread:耗时 操作 提高程序性能 1个力工:1个月...10个力工:3天~5天 (2)线程有哪些开销 空间上 开销 数据结构上 开销 C# :Thread CLR:Thread(C++写 ) OS:Thread 线程栈开销...dllmain 托管 dll 上面上游 dllmain thread 在start时 会通知这些 托管 dll thread 在exit时 也会通知这些 托管 dll (资源清理)...Task:基于ThreadPool 上层封装 线程池 使用及分析其设计思想 (1) 为什么 要使用线程池?...Task及如何运用其编排能力 (1)Task 设计思想 为什么 会出现Task: 获取 Thread 返回值比较麻烦 多个Thread 串行实现比较麻烦 Thread 父子关系实现比较麻烦(比如

    472 3 0

    苏州同程旅游学长给我 全面的面试知识库

    我们已经介绍了50多种基本知识,以推进常见 C# 面试问题和答案 2、什么是 C# C# 是一种面向对象 ,类型安全 托管 语言,由.Net框架编译以生成Microsoft中间语言。...不,不能执行多个类似类型 捕获块。一旦执行了 正确 捕获代码,控制就会转移到finally块,然后执行finally块之后 代码。 5、 public,static和void之间有什么区别?...我们可以轻松地将自定义控件添加到多个应用程序(如果共享 Dll )。因此,如果它们是私有的,那么我们可以将其复制到 dll 到Web应用程序 bin目录中,然后添加引用并可以使用它们。...他们有自己 设计和代码背后。用户控件 文件扩展名为ascx。 17、 C# 密封类是什么? 当我们想限制继承 类时,我们创建密封 类。密封 修饰符,用于防止 类派生。...当我们希望对象与它们一起释放任何 托管 资源时,将调用Dispose()。另一方面,Finalize()用于相同 目的,但不能保证对象 垃圾回收。 28、什么是循环引用?

    3K 2 0

    C# 面试题

    Attribute特性就是关联了一个目标对象 一段配置信息,本质上是一个类,其为目标元素提供关联附加信息,这段附加信息存储在 dll 元数据,它本身没什么意义。运行期以反射 方式来 获取 附加信息。...using() 只是一种语法形式,其本质还是try…finally 结构,可以保证Dispose始终会被执行。 8. 解释一下 C# 析构函数? 为什么 有些编程建议里不推荐使用析构函数呢?...finalize不能保证立即释放 托管 资源,Finalizer被执行 时间是在对象不再被引用后 某个不确定 时间;而dispose一调用便释放 托管 资源。...Dispose一调用便释放 托管 资源; Finalize不能保证立即释放 托管 资源,Finalizer被执行 时间是在对象不再被引用后 某个不确定 时间; 11. .NET中 托管 堆中是否可能出现内存泄露 现象...比如: 不 正确 使用静态字段,导致大量数据 无法 被GC释放; 没有 正确 执行Dispose(), 托管 资源没有得到释放; 不 正确 使用终结器Finalize(),导致 无法 正常释放资源; 其他不 正确 引用,导致大量 托管 对象 无法

    769 2 0

    C# DllImport 用法

    大家在实际工作学习 C# 时候,可能会问: 为什么 我们要为一些已经存在 功能(比如Windows中 一些功能,C++中已经编写好 一些方法)要重新编写代码, C# 有没有方法可以直接都用这些原本已经存在 功能呢...答案是肯定 ,大家可以通过 C# DllImport直接调用这些功能。...DllImportAttribute 属性提供对 托管 DLL 导出 函数进行调用所必需 信息。作为最低要求,必须提供包含入口点 DLL 名称。...我们 托管 定义开始: typedef struct _SYSTEM_POWER_STATUS { BYTE  ACLineStatus; BYTE  BatteryFlag; BYTE ...,因此我们使用 byte 作为该 enum 基本类型 示例四:处理字符串 二 C# 中调用C++代码