如何编写通用 C 函数来调用 Win32 函数?

2024-04-27

为了允许从脚本语言(用 C 编写)访问 Win32 API,我想编写一个如下所示的函数:

void Call(LPCSTR DllName, LPCSTR FunctionName, 
  LPSTR ReturnValue, USHORT ArgumentCount, LPSTR Arguments[])

一般来说,它将调用任何 Win32 API 函数。

(LPSTR 参数本质上用作字节数组 - 假设它们的大小已正确调整以获取函数外部的正确数据类型。此外,我认为需要一些额外的复杂性来区分指针和非指针参数,但我为了这个问题的目的,我忽略了这一点)。

我遇到的问题是将参数传递到 Win32 API 函数中。因为这些是 stdcall,所以我不能使用 varargs,所以“Call”的实现必须提前知道参数的数量,因此它不能是通用的......

我想我可以用汇编代码来做到这一点(通过循环参数,将每个参数推入堆栈),但这在纯 C 中可能吗?

Update:我已将“不,不可能”的答案标记为目前已接受。如果基于 C 的解决方案出现,我当然会改变这一点。

Update: ruby/dl http://www.jbrowse.com/text/rdl_en.html看起来它可以使用合适的机制来实现。任何有关这方面的细节将不胜感激。


首先,您不能在 C 中将类型作为参数传递。剩下的唯一选择是宏。

这个方案只需稍加修改即可工作(参数为 void * 数组),前提是您正在执行LoadLibrary/GetProcAddress调用 Win32 函数。否则,拥有函数名称字符串将毫无用处。在 C 中,调用函数的唯一方法是通过其名称(标识符),在大多数情况下,该名称会衰减为指向该函数的指针。您还必须负责转换返回值。

我最好的选择:

// define a function type to be passed on to the next macro
#define Declare(ret, cc, fn_t, ...) typedef ret (cc *fn_t)(__VA_ARGS__)

// for the time being doesn't work with UNICODE turned on
#define Call(dll, fn, fn_t, ...) do {\
    HMODULE lib = LoadLibraryA(dll); \
    if (lib) { \
        fn_t pfn = (fn_t)GetProcAddress(lib, fn); \
        if (pfn) { \
            (pfn)(__VA_ARGS__); \
        } \
        FreeLibrary(lib); \
    } \
    } while(0)

int main() {
    Declare(int, __stdcall, MessageBoxProc, HWND, LPCSTR, LPCSTR, UINT);

    Call("user32.dll", "MessageBoxA", MessageBoxProc, 
          NULL, ((LPCSTR)"?"), ((LPCSTR)"Details"), 
          (MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2));

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

如何编写通用 C 函数来调用 Win32 函数? 的相关文章

  • 在动态事件处理程序中引用“this”

    在我的 myClass 类中 我使用 Reflection Emit 为 myClass 类成员之一动态编写事件处理程序 我已经成功地做到了这一点 现在 我想修改事件处理程序以调用 myClass 类中的实例方法之一 但是 我无法弄清楚如何
  • C# 中四舍五入到偶数

    我没有看到 Math Round 的预期结果 return Math Round 99 96535789 2 MidpointRounding ToEven returning 99 97 据我了解 MidpointRounding ToE
  • 找到的程序集的清单定义与程序集引用不匹配

    我试图在 C Windows 窗体应用程序 Visual Studio 2005 中运行一些单元测试 但出现以下错误 System IO FileLoadException 无法加载文件或程序集 实用程序 版本 1 2 0 200 文化 中
  • Qt 计算和比较密码哈希

    目前正在 Qt 中为测验程序构建面向 Web 的身份验证服务 据我了解 在数据库中存储用户密码时 必须对其进行隐藏 以防落入坏人之手 流行的方法似乎是添加的过程Salt https en wikipedia org wiki Salt cr
  • Paradox 表 - Oledb 异常:外部表不是预期的格式

    我正在使用 Oledb 从 Paradox 表中读取一些数据 我遇到的问题是 当我将代码复制到控制台应用程序时 代码可以工作 但在 WinForms 中却不行 两者都以 x86 进行调试 我实际上只是复制代码 在 WinForms 应用程序
  • 是否有像 gccxml 这样的用于生成包装器的 C 标头解析器工具?

    我需要为一种新的编程语言编写一些 C 标头包装器 并且想要类似 gccxml 的东西 但不完全依赖 gcc 以及它在 Windows 系统上带来的问题 只需要读C而不是C 只要有完整的文档记录 任何格式的输出都可以 Linux Solari
  • 在 MATLAB 中创建共享库

    一位研究人员在 MATLAB 中创建了一个小型仿真 我们希望其他人也能使用它 我的计划是进行模拟 清理一些东西并将其变成一组函数 然后我打算将其编译成C库并使用SWIG https en wikipedia org wiki SWIG创建一
  • 默认值 C# 类 [重复]

    这个问题在这里已经有答案了 我在控制器中有一个函数 并且我收到表单的信息 我有这个代码 public Actionresult functionOne string a string b string c foo 我尝试将其转换为类似的类
  • 编译器错误“错误:在文件范围内可变地修改了‘字符串’”

    考虑 include
  • 无法加载文件或程序集“EntityFramework,版本=6.0.0.0”

    我究竟做错了什么 我该如何解决这个问题 我有一个包含多个项目的解决方案 它是一个 MVC NET 4 5 Web 应用程序 在调试模式下启动后调用其中一个项目时 出现此错误 导致此错误的项目具有以下参考 两个都是版本6 0 0 0 应用程序
  • 防止GDB中的PLT(过程链接表)断点

    在最新版本的 GDB 中 在库函数调用上设置断点会导致多个实际断点 调用过程链接表 PLT 实际的函数调用 这意味着当调用库函数时 我们每次都会经历两次中断 在以前的 GDB 版本中 只会创建 2 因此您只能得到一次中断 那么问题来了 是否
  • C#中Enum中定义的value__是什么

    What value 可能在这里 value MSN ICQ YahooChat GoogleTalk 我运行的代码很简单 namespace EnumReflection enum Messengers MSN ICQ YahooChat
  • 使用 AdHocWorkspace 会导致“不支持语言‘C#’”。

    在VS2015中使用Microsoft CodeAnalysis CSharp Workspaces的RC2 这段代码会抛出异常 var tree CSharpSyntaxTree ParseText var workspace new A
  • 错误左值需要作为赋值C++的左操作数

    整个程序基本上只允许用户移动光标 如果用户位于给定的坐标范围 2 2 内 则允许用户键入输入 我刚刚提供了一些我认为足以解决问题的代码 我不知道是什么导致了这个问题 你能解释一下为什么会发生吗 void goToXY int int 创建一
  • 如何获取 QIcon 的文件/资源​​路径

    假设我做了这样的事情 QIcon myIcon resources icon ico 我稍后如何确定该图标的路径 例如 QString path myIcon getPath 问题是 没有getPath 会员 我找不到类似的东西 但肯定有办
  • C++ [Windows] 可执行文件所在文件夹的路径[重复]

    这个问题在这里已经有答案了 我需要访问一些文件fstream在我的 Windows 上的 C 应用程序中 这些文件都位于我的exe文件所在文件夹的子文件夹中 获取当前可执行文件的文件夹路径的最简单且更重要的 最安全的方法是什么 Use 获取
  • 从有符号字符转换为无符号字符然后再转换回来?

    我正在使用 JNI 并有一个 jbyte 类型的数组 其中 jbyte 表示为有符号字符 即范围从 128 到 127 jbyte 表示图像像素 对于图像处理 我们通常希望像素分量的范围为0到255 因此 我想将jbyte值转换为0到255
  • g++ C++0x 枚举类编译器警告

    我一直在将可怕的 C 类型安全伪枚举重构为新的 C 0x 类型安全枚举 因为它们是way更具可读性 不管怎样 我在导出的类中使用它们 所以我明确地将它们标记为导出 enum class attribute visibility defaul
  • 无法使 Polly 超时策略覆盖 HttpClient 默认超时

    我正在使用 Polly 重试策略 并且正如预期的那样 在重试过程中HttpClient达到 100 秒超时 我尝试了几种不同的方法来合并 Polly 超时策略 将超时移至每次重试而不是总计 但 100 秒超时仍然会触发 我读过大约 5 个
  • FindAsync 很慢,但是延迟加载很快

    在我的代码中 我曾经使用加载相关实体await FindAsync 希望我能更好地遵守 C 异步指南 var activeTemplate await exec DbContext FormTemplates FindAsync exec

随机推荐

  • 如何使用 ASP classic 进行重定向

    我想从一个 URL 重定向到另一个 URL http female deals com http male deals com 如何通过在浏览器中将 URL 更改为新 URL 以及页面直接转到新 URL 而无需转到旧 URL 并进行刷新来实
  • Py2Exe“缺少以下模块”

    使用 Py2Exe 时 我收到警告 例如 The following modules appear to be missing Crypto Crypto Cipher Crypto Hash Padding 由于找不到这些模块 导致 EX
  • 使用嵌套 C++ 类和枚举的优点和缺点?

    使用嵌套公共 C 类和枚举的优点和缺点是什么 例如 假设您有一个名为printer 并且此类还存储输出托盘上的信息 您可以 class printer public std string name enum TYPE TYPE LOCAL
  • 同一服务器,SSL 和非 SSL

    Apache 2 x 中是否可以在同一服务器上同时运行 SSL 协议和非 SSL 协议 所以如果我访问http example com 非 SSL 和https example com SSL 它们都可用 如果是这样 我需要创建一个虚拟主机
  • DirectX 世界视图矩阵乘法 - GPU 或 CPU 的地方

    我是 directx 的新手 但令我惊讶的是 我看到的大多数示例中 世界矩阵和视图矩阵都是作为顶点着色器的一部分相乘 而不是与 CPU 相乘并将结果传递给着色器 对于刚性对象 这意味着您为对象的每个顶点将相同的两个矩阵相乘一次 我知道 GP
  • 是否有针对非视网膜显示的媒体查询?

    根据关于 CSS 技巧的文章 https css tricks com snippets css retina display media query 面向未来的视网膜显示媒体查询可以写为 media only screen and web
  • 如何将 JMX 绑定到特定接口?

    我目前正在启动我的 Java VMcom sun management jmxremote 属性 以便我可以通过 JConsole 连接到它进行管理和监控 不幸的是 它监听机器上的所有接口 IP 地址 在我们的环境中 经常会出现多个 Jav
  • 处理 Javascript 中的浮点精度[重复]

    这个问题在这里已经有答案了 我有大量数值y在 JavaScript 中 我想通过将它们四舍五入到最接近的倍数来对它们进行分组x并将结果转换为字符串 如何解决烦人的浮点精度 例如 0 2 0 4 0 6000000000000001 我尝试过
  • 解析嵌套的 JSON Swift 3 [重复]

    这个问题在这里已经有答案了 我正在尝试在 Swift 3 中解析复杂的 JSON 文件 我在获取值时遇到问题 我找到了一些示例代码并尝试对其进行了一些调整 但它不起作用我当前收到错误 Type NSArray 没有下标成员 我什至不确定这是
  • WebStorm/PHPStorm 中的智能选项卡有什么作用?

    我对智能选项卡在一般偏好中的作用感到困惑 它说 仅通过空格即可对必要的列进行精细对齐 如果 如果未选中此复选框 则使用空格进行对齐 必要的 这是否意味着在这两种情况下都使用空格来对齐 这是否意味着它总是在后者中使用空格 而仅有时在前者中使用
  • 如何根据功能(自动)通过属性查看或隐藏字段?

    我只想查看员工 他的经理和 hr group hr user 组的 working hours 字段 如何隐藏该字段自动执行 无需编辑表单或触发按钮 class InheritHrEmployee models Model inherit
  • Grails“max”带有关联的子查询,仅获取最新的 hasMany

    简化的域模型 Txn 如交易中 有许多 TxnStatus TxnStatus 有一个日期时间 这是一个遗留映射 所以我无法更改 DB Txn 上的映射 static mapping txnStatus column MessageID i
  • JavaScript 运行时错误:无法获取未定义或空引用的属性“msie”

    我只是尝试更改我的 jquery ui 对母版页的引用 我仅在 Internet Explorer 上收到上述错误 我在 Firefox 和 Chrome 上没有收到错误消息 这是抛出错误的 jquery 代码 return a brows
  • 仅横向应用程序中的 GameCenter 身份验证抛出 UIApplicationInvalidInterfaceOrientation

    问题 如果用户未登录 GameCenter 帐户 GameCenter 身份验证视图以纵向模式启动 在 ios 5 中 有一个模式对话框 要求登录 但是如果我在 xcode 项目摘要 或supportedInterfaceOrientati
  • 根据使用频率随机生成字母?

    如何根据常用语音中的使用频率随机生成字母 任何伪代码都值得赞赏 但如果用 Java 实现就更棒了 否则 只需朝正确的方向戳一下就会有所帮助 注意 我不需要生成使用频率 我确信我可以很容易地查找到它 我假设您将频率存储为 0 到 1 之间的浮
  • 使用IntelliJ编译Java 7,配置麻烦

    我正在使用 IntelliJ 并尝试让它与 Java 7 一起工作 我的 JDK 设置为指向最新的 JDK 此外 项目也设置使用它 然而 当尝试编写 Java7 代码时 它的语法无法被识别 请问我缺少什么 Set the 项目语言水平 to
  • 如何计算Java数组的内存大小?

    我知道如何通过添加三个部分来计算Java对象的内存大小 标头 属性 引用 我还知道Java数组也是一个对象 但是当我读到 Understanding the JVM Advanced Features and Best Practices
  • 如何检查 C# 中动态匿名类型上是否存在属性?

    我有一个匿名类型对象 我从方法中以动态方式接收该对象 我想检查该对象上是否存在属性 var settings new Filename temp txt Size 10 function void Settings dynamic sett
  • ANSI C - 清除字符串

    我有一个这样声明的字符串 str malloc sizeof char 128 我想彻底清除它 这样当我这样做时strncat 操作时 新字符将被写入到开头str 我需要清除它的原因是我正在用它本身的简化版本重写它 删除多余的空格 我建议你
  • 如何编写通用 C 函数来调用 Win32 函数?

    为了允许从脚本语言 用 C 编写 访问 Win32 API 我想编写一个如下所示的函数 void Call LPCSTR DllName LPCSTR FunctionName LPSTR ReturnValue USHORT Argume