我用Visual Studio创建了一个COM对象,我想用Delphi。
[Guid("9D0CCD2D-75E9-46AC-BC40-C4D84669FC45")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IMyComClassDispatch
{
string PropertyString { get; set; }
string funcGetString();
void funcSetString(string aString);
}
[ClassInterface(ClassInterfaceType.None)]
public class MyComClassDispatch : IMyComClassDispatch
{
public string PropertyString { get; set; }
public string varString;
public string funcGetString()
{
return varString;
}
public void funcSetString(string aString)
{
varString = aString;
}
}
然后我生成了tlb文件,最后是一个与我的COM对象对应的pascal文件,其中tlibimp.exe与Delphi 5捆绑在一起:
C:\>tlibimp.exe -P+ mylib.tlb
这是生成的代码:
// *********************************************************************//
// DispIntf: IMyComClassDispatch
// Flags: (4096) Dispatchable
// GUID: {9D0CCD2D-75E9-46AC-BC40-C4D84669FC45}
// *********************************************************************//
IMyComClassDispatch = dispinterface
['{9D0CCD2D-75E9-46AC-BC40-C4D84669FC45}']
property PropertyString: WideString readonly dispid 1610743808;
function funcGetString: WideString; dispid 1610743810;
procedure funcSetString(const aString: WideString); dispid 1610743811;
end;
问题是我的属性被标记为只读,我不明白为什么会发生这种情况,因为这个工具也可以生成C ++代码并且可以修改属性:
// *********************************************************************//
// Interface : IMyComClassDispatch
// Indicateurs : (4096) Dispatchable
// GUID : {9D0CCD2D-75E9-46AC-BC40-C4D84669FC45}
// *********************************************************************//
interface IMyComClassDispatch : public TDispWrapper<IDispatch>
{
BSTR __fastcall get_PropertyString()
{
_TDispID _dispid(/* PropertyString */ DISPID(DISPID_UNKNOWN/*[1610743808]*/));
TAutoArgs<0> _args;
OlePropertyGet(_dispid, _args);
return _args.GetRetVariant();
}
void __fastcall set_PropertyString(BSTR Param1/*[in]*/)
{
_TDispID _dispid(/* PropertyString */ DISPID(1610743808));
TAutoArgs<1> _args;
_args[1] = Param1 /*[VT_BSTR:0]*/;
OlePropertyPut(_dispid, _args);
}
BSTR __fastcall funcGetString()
{
_TDispID _dispid(/* funcGetString */ DISPID(DISPID_UNKNOWN/*[1610743810]*/));
TAutoArgs<0> _args;
OleFunction(_dispid, _args);
return _args.GetRetVariant();
}
void __fastcall funcSetString(BSTR aString/*[in]*/)
{
_TDispID _dispid(/* funcSetString */ DISPID(DISPID_UNKNOWN/*[1610743811]*/));
TAutoArgs<1> _args;
_args[1] = aString /*[VT_BSTR:0]*/;
OleProcedure(_dispid, _args);
}
__property BSTR PropertyString = {read = get_PropertyString, write = set_PropertyString};
};
这是否意味着我应该避免使用COM对象的属性,还是有任何我应该更改的选项?这是tlibimp的问题还是编译器的限制,无法生成写入COM对象属性的指令?
任何帮助都会受到赞赏!
答案 0 :(得分:1)
这是Delphi 5中的已知缺陷。 6 tlibimp.exe。您应升级到Delphi 7或更新版本以避免它。
答案 1 :(得分:0)
Tlibimp.exe在Delphi 5中被窃听,并且没有Borland / CodeGear / Embarcadero的支持......
解决方法是删除生成的pas文件上的只读标记。但为了确保代码被正确调用,我做了一些修改以证明它有效:
在COM对象类中,写入setter中的文件:
public string PropertyString
{
get { return varString; }
set
{
varString = value;
File.WriteAllText(@"C:\Users\elias\Documents\com.txt", varString);
}
}
删除tlibimp.exe生成的.pas文件中属性的只读标记:
// *********************************************************************//
// DispIntf: IMyComClassDispatch
// Flags: (4096) Dispatchable
// GUID: {9D0CCD2D-75E9-46AC-BC40-C4D84669FC45}
// *********************************************************************//
IMyComClassDispatch = dispinterface
['{9D0CCD2D-75E9-46AC-BC40-C4D84669FC45}']
property PropertyString: WideString dispid 1610743808;
function funcGetString: WideString; dispid 1610743810;
procedure funcSetString(const chaine: WideString); dispid 1610743811;
end;
然后您可以使用COM对象:
var
MyClass: IMyComClassDispatch;
begin
try
MyClass:= CoMyComClassDispatch.Create;
MyClass.PropertyString:= 'some value';
finally
MyClass._Release;
end;
end;
文件写得正确!
现在这是我在项目中遇到的唯一问题,希望以后我不会遇到任何其他问题......