作为Delphi中的新手,我遇到了外部API的问题。 这个外部API期望一个带有一个或两个值的参数,我认为这称为按位参数。 在Delphi中,这是通过一组
完成的基本是枚举。
TCreateImageTask = (
citCreate = 1,
citVerify
);
我已将其放入一组:
TCreateImageTasks = set of TCreateImageTask
在函数中,我用以下命令填充该集合:
function TfrmMain.GetImageTask: TCreateImageTasks;
begin
Result:=[];
if chkCreate.checked then Include(Result, citCreate);
if chkVerify.checked then Include(Result, citVerify);
end;
现在我必须将此任务交给一个用C ++编写的外部DLL DLL需要一个 __ int8 值。它可能包含一个或两个TCreateImageTasks。在C ++中,通过:
__int8 dwOperation = 0;
if (this->IsDlgButtonChecked(IDC_CHECK_CREATE))
{
dwOperation = BS_IMGTASK_CREATE;
}
if (this->IsDlgButtonChecked(IDC_CHECK_VERIFY))
{
dwOperation |= BS_IMGTASK_VERIFY;
}
int32 res = ::CreateImage(cCreateImageParams, dwOperation);
所以我必须将我的一组转换为整数。我这样做
function TfrmMain.SetToInt(const aSet;const Size:integer):integer;
begin
Result := 0;
Move(aSet, Result, Size);
end;
我打电话给
current task := GetImageTask;
myvar := SetToInt(currentTask, SizeOf(currentTask));
我现在遇到的问题是,当2个值位于集合中时,myvar为6;如果仅在集合内部创建,则为2;如果仅在集合内部进行验证,则为4。在我看来,这看起来不正确,并且外部DLL不知道此值。
我的错在哪里?
答案 0 :(得分:1)
我想当您在= 1
的声明中删除TCreateImageTask
时,它起作用吗?
= 1
会将序数值移位1,以给出您看到的结果,但可能不是必需的。为此,我们需要了解BS_IMGTASK_CREATE
和BS_IMGTASK_VERIFY
的值。
我的精神力量告诉我BS_IMGTASK_CREATE = 1
和BS_IMGTASK_VERIFY = 2
。假设这些是位掩码,则它们对应于值2^0
和2^1
。这与序数0和1相匹配。
因此您应该声明
TCreateImageTask = (citCreate, citVerify);
将citCreate
映射到0,将citVerify
映射到1。
答案 1 :(得分:0)
这就是所谓的按位运算!
在Windows API的Delphi实现中广泛使用将SET转换为LONGWORD。
这就是您要寻找的:
How to save/load Set of Types?
这里也已经回答了: