为了允许从脚本语言(用C编写)访问Win32 API,我想编写如下函数:
void Call(LPCSTR DllName, LPCSTR FunctionName,
LPSTR ReturnValue, USHORT ArgumentCount, LPSTR Arguments[])
Run Code Online (Sandbox Code Playgroud)
一般来说,它会调用任何Win32 API函数.
(LPSTR参数基本上用作字节数组 - 假设它们的大小正确,以便在函数外部采用正确的数据类型.另外我认为需要一些额外的复杂性来区分指针和非指针参数但我为了这个问题的目的,我忽略了这一点.
我遇到的问题是将参数传递给Win32 API函数.因为这些是stdcall我不能使用varargs所以'Call'的实现必须提前知道参数的数量,因此它不能是通用的...
我想我可以使用汇编代码(通过循环遍历参数,将每个推送到堆栈)来实现这一点但是在纯C中这是可能的吗?
更新:我已经标记了现在接受的'不可能'答案.如果基于C的解决方案曝光,我当然会改变这一点.
更新: ruby/dl看起来可能使用合适的机制实现.任何有关这方面的细节将不胜感激.
我正在尝试在RSPEC(ruby风味的BDD)和Windows应用程序之间编写一个接口.应用程序本身是用一种晦涩的语言编写的,但它有一个C API来提供访问.我已经使用Ruby/DL,但是即使是最基本的DLL方法调用也很困难.这是我到目前为止,在一个名为gt4r.rb的文件中:
require 'dl/import'
module Gt4r
extend DL::Importable
dlload 'c:\\gtdev\\r321\\bin\\gtvapi'
# GTD initialization/termination functions
extern 'int GTD_init(char *[], char *, char *)'
extern 'int GTD_initialize(char *, char *, char *)'
extern 'int GTD_done(void)'
extern 'int GTD_get_error_message(int, char **)'
end
Run Code Online (Sandbox Code Playgroud)
到目前为止,我的阅读表明这是我需要的所有内容,所以我写了一个RSPEC示例:
require 'gt4r'
@@test_environment = "INCLUDE=C:\\graphtalk\\env\\aiadev\\config\\aiadev.ini"
@@normal_user = "BMCHARGUE"
describe Gt4r do
it 'initializes' do
rv = Gt4r.gTD_initialize @@normal_user, @@normal_user, @@test_environment
rv.should == 0
end
end
Run Code Online (Sandbox Code Playgroud)
当跑...
C:\code\GraphTalk>spec -fs -rgt4r gt4r_spec.rb
Gt4r
- initializes (FAILED - 1)
1)
'Gt4r initializes' FAILED …
Run Code Online (Sandbox Code Playgroud)