开发者

C# late binding to com/activeX server, trouble with one method

I am fairly new to Interop/Com/ActiveX etc, so bear with me.

I am late binding into a com/activex (not sure which one) server (basically an exe not a dll). I am successfully using all the methods in that server except for one, here is the description:

VT_INT GetLastCCTError (variant *error_string);

Description: This function is used to retrieve the last error generated by the CCT. The function may be called at any point as long as the CCT Server is initialized. If no error has occurred when the function is called, the returned code is ‘0’ (zero), and the error string will be empty. Only the last error that occurred during the current run of the CCT Server will be available.

Input: None

Output: The function returns a single output parameter, ‘error_string’ of type VARTYPE VT_BSTR | VT_BYREF. The parameter contains an error string for the error code associated with the last CCT function failure. Return Value: This function returns an integer value of type VT_INT. This is the error code associated with the last CCT function failure

I first tried using this code:

this.LastErrorCode = (int)CCTType.InvokeMember("GetLastCCTError开发者_JAVA百科", BindingFlags.InvokeMethod, null, CCTObject, new object[] {this.LastErrorString});

I got the following exception: Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH)

Then after some thinking I changed the code to:

object[] Args = { "SomeString" };

this.LastErrorCode = (int)CCTType.InvokeMember("GetLastCCTError", BindingFlags.InvokeMethod, null, CCTObject, Args);

Still the same error. After some googling, I found this article: http://www.informit.com/articles/article.aspx?p=27219&seqNum=8

If you look at section 3.3 it seems to be the solution to my problem, and thus I changed my code to:

object[] Args = { "SomeString" };

ParameterModifier ParMod = new ParameterModifier(1);
ParMod[0] = true;
ParameterModifier[] ArrParMod = { ParMod };

this.LastErrorCode = (int)CCTType.InvokeMember("GetLastCCTError", BindingFlags.InvokeMethod, null, CCTObject, Args, ArrParMod, null, null);

this.LastErrorString = (string) Args[0];

This still results in the same exception. I am now thinking that the problem might not be the reference passing but something else. Any help will be appreciated.


Is this because strings in C# are immutable.

"SomeString" will be resolved by the compiler as an unchangeable string on the managed memory (stack or heap is largely irrelevant in your case).

So, in a way you are not passing in a string reference but a literal - something that could never be an 'out' parameter as in your example ... so the marshalling won't do what it thinks (knows) would be a bad idea.

Andrew D, I suspect, is right.

Might suggest you try something like:

StringBuilder errorMessage = new StringBuilder();

this.LastErrorCode = (int)CCTType.InvokeMember("GetLastCCTError", BindingFlags.InvokeMethod, null, CCTObject, errorMessage );

this.LastErrorString = errorMessage.ToString();

Regards,

Aidanapword

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜