【问题标题】:Use functions in C# from unmanaged C-DLL (AccessViolationException)在非托管 C-DLL 中使用 C# 中的函数 (AccessViolationException)
【发布时间】:2015-02-14 10:50:23
【问题描述】:

我有一个带有简短文档的 C-DLL,我想在我的 C# 程序中使用这个 DLL。

不幸的是,文档是针对受密码保护的 Excel-Makro 的,所以我不知道确切的函数名称和参数类型。

我使用 DependencyWalker 查找 DLL 的所有导出函数,并结合文档发现文档中的函数 ptx 被称为 FU_PTX 在 DLL 中,需要一个参数并有一个返回值。不幸的是我仍然不知道参数的类型或返回值,但我知道它是一个数字。

所以我写了以下代码:

...
        [DllImport("dmata.dll")]
        public static extern UInt32 FU_PTX(UInt32 x);

        FU_PTX(11); 
...

此代码引发 AccessViolationException。我还尝试了其他类型,如 int、long、double 但我总是遇到同样的异常。

据我所知,没有办法直接从 dll 中获取所需的类型,但也许有人知道可能出了什么问题,或者可以为我指明正确的方向。


编辑:

我设法从 vba 文件中获取签名:

Private Declare Function FU_PTX# Lib "dmata.dll" (FT#)

我将此移植到以下 C# 代码:

[DllImport("dmata.dll")]
public static extern double FU_PTX(double x);


FU_PTX(1.5);

我仍然收到相同的 AccessViolationException。 有人知道为什么我仍然会遇到同样的异常吗?

【问题讨论】:

  • 如果你不知道函数的签名,成功调用它几乎是绝望的——你最好的办法就是得到它。对于初学者,参数可以是指向具有特定字段的结构的指针(即使它是“数字”也是如此——它可以是VARIANT),或者调用约定可以是cdecl而不是@987654327 @。看看你是否可以获得一个声明函数原型的头文件(.h)。如果有人编写此 DLL 以使其被使用,则必须有关于签名 somewhere 的文档。
  • 如果有人问我除了is this helpful之外什么都否认?
  • @Jeroen Mostert:感谢您的评论。这是一个用于 Excel 的非常古老的 DLL。该文档仅说明了函数名称和输入/输出参数,但没有说明它们的类型。 DLL 执行一些复杂的数学函数,我希望在 C# 中实现比在 Excel 中更好的用户体验。我认为我没有机会获得头文件或签名。
  • @rene 我觉得这很有用,谢谢 :)
  • 如果 DLL 是从 Excel 中使用的,这意味着它打算从 VBA 中调用。如果您已成功删除密码保护并拥有调用此函数的 VBA 代码,则可以对调用进行逆向工程。如果您需要帮助,请将其添加到您的问题中。

标签: c# dll dllimport access-violation


【解决方案1】:

这个语法:

Private Declare Function FU_PTX# Lib "dmata.dll" (FT#)

使用# 后缀相当晦涩;在“现代”VBA(如果可以说是这样的话)声明将是

Private Declare Function FU_PTX Lib "dmata.dll" (ByRef FT As Double) As Double

注意ByRef 的不幸默认值;默认情况下,参数在 VBA 中通过引用传递(即使函数无意修改它们)。

这应该与以下 C# 声明相对应:

[DllImport("dmata.dll")]
public static extern double FU_PTX(ref double FT);

由于参数是通过引用传递的,所以不能传递常量,必须始终使用变量:

double ft = 11.0;
FU_PTX(ref ft);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-19
    • 2016-02-09
    相关资源
    最近更新 更多