情况是这样的:我有一个带有dll的条形码扫描器(用C ++编写,所有函数都是stdcall),它输出所有必要的函数来与之通信。并且有几个函数应该用于分配回调(我必须提供适当的过程,并且一旦某些事件触发就会调用它们)。这是我面临的主要问题。这些回调分配功能只能接受“独立”程序(在这种情况下一切正常),但不接受方法甚至是匿名程序。在这些事件中,我必须访问一些类数据(扫描仪实现为类),如字段和方法,但通常不能从独立的单元过程。你能帮我解决这个问题吗?
一些代码:
扫描仪API说明:
typedef void (__stdcall *TOnDevicePlug)(bool PluggedIn);
extern "C" __declspec(dllexport) void __stdcall SetupOnDevicePlugCallback(TOnDevicePlug OnPresent);
我的类型说明:
TOnDevicePlug = procedure(PluggedIn: Boolean); stdcall;
TSetupOnDevicePlugCallback = function(AOnPresent: TOnDevicePlug): Integer; stdcall;
如果我喜欢这样:
procedure OnDevicePlug(PluggedIn: Boolean); stdcall;
begin
Form2.mmLog.Lines.Add('On plugged activated');
end;
...
@FSetupOnDevicePlugCallback := GetProcAddress(FDllHandle, 'SetupOnDevicePlugCallback');
FSetupOnDevicePlugCallback(OnDevicePlug);
...
一切正常。 (但同样,我无法与我的班级合作)。
如果我尝试这样的话:
FOnPlug := TOnDevicePlug(
procedure stdcall
begin
mmLog.Lines.Add('On plugged activated');
end
);
FSetupOnDevicePlugCallback(FOnPlug);
其中FOnPlug - TOnDevicePlug类的类字段。在这种情况下,有两种变体:如果我留下旧类型描述(TOnDevicePlug = procedure(PluggedIn: Boolean); stdcall;
),我将获得“特权指令”的异常。如果我将类型更改为“引用过程”(如TOnDevicePlug = reference to procedure stdcall;
),则会出现访问冲突异常。这两个错误都是在事件中触发的。
那么你可以告诉我一些事情,让这个活动与我的班级一起工作吗?任何想法都会感激不尽。或许你会在我的代码中看到一些错误。
答案 0 :(得分:1)
您的回调必须采用以下格式:
procedure MyOnDevicePlug(PluggedIn: Boolean); stdcall;
begin
// do stuff
end;
匿名方法根本不兼容。写一个单位范围的程序,如下所示:
var express = require('express'),
request = require('request'),
bodyParser = require('body-parser');
var app = express();
function createMainPage (req, res, msg) {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
var result = '<html><head><script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>';
result += '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">';
result += '<link rel="stylesheet" href="https://bootswatch.com/cerulean/bootstrap.min.css">';
result += '<title> Demo </title>';
result += '</head><body><br /><br /><br /><div class="container">';
result += '<form class="form-horizontal" method="post"><fieldset><legend> Demo </legend>';
result += '<br /><h2><center>Please enter your Phone Number</center></h2> <br /> <br />';
result += '<div class="col-lg-2 col-lg-offset-5">';
result += '<input type="text" class="form-control" id="inputphonenumber" name="inputphonenumber"placeholder="+33XXXXXXXXX"></div>';
result += '</fieldset></div><br/><p style="text-align:center; font-weight:700; font-size:1.2em;">' + msg + '</dialog></p><br /><br /><br />';
//
//msg here is the parameter that i want to show on a modal windows after click on submit button
//
result += '<div class="form-group"><div class="col-lg-10 col-lg-offset-6">';
result += '<button type="reset" class="btn btn-default">Cancel</button>';
result += '<button type="submit" class="btn btn-primary">Submit</button></form>';
result += '<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>';
result += '</body></html>';
res.send(result);
}
app.set('port', (process.env.PORT || 8080)); // cannot force 80
app.use(bodyParser.urlencoded({extended: false}));
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res, next) {createMainPage(req, res, "")
});
app.post('/', function(req, res, next) {
var myText = req.body.inputphonenumber;
//......
// I do some operations to finally get the parameter "message"
//......
createMainPage(req, res, customMessage);}
app.listen(app.get('port'), function() {
console.log('userDetails Node app is running on port',
app.get('port'));
});
现在,您正在使用的库在调用此回调时不会提供任何其他信息。它不传递额外的指针,以允许回调接收者访问其状态。
您可以修改您使用的库,以便在调用它时接受无类型指针,然后在回调中将该指针传递给您。
如果你不能进行这样的修改,那么你可能需要使用全局变量,甚至thunk来获得状态。