سؤال

How can I convert this Clarion procedure declaration to C#? It's part of a 3rd Party DLL written in C, which doesn't have much documentation. I have listed the prototype for the method in Clarion that is working correctly. In C#, I'm not sure what type to use to replace *CString. I tried char[] like @DanielC suggested, but it didn't work. I also found that Clarion long is 32-bit (thanks @shf301).

Clarion:

SendRequest Procedure(*CString xData,Long DataLen,Long xTimeout),Byte,Virtual

C# (what I've tried, which doesn't work):

[DllImport("3RD_PARTY_API.dll")]
private static extern long SendRequest(ref string xData, int DataLen, int xTimeout);

When I call the SendRequest method in C# I get the standard PInvokeStackImbalance was detected error from VS2010. I think it's an issue of the parameter types and not something like CharSet or EntryPoint in the DllImport declaration. I'm really just stuck on how to convert *CString to a valid C# type.

هل كانت مفيدة؟

المحلول

I found the answer. I wish I still worked with the developer who wrote this code so I could yell at them. They put a wrapper around the API so that the method I listed with 3 parameters then calls the actual API without the timeout value. The PInvokeStackImbalance exception came from the fact that I was adding in an extra parameter.

Here is the actual Clarion procedure as well as the correct C# syntax for this:

Clarion:

SendRequest Procedure(*CString xData, Long DataLen), Byte, Virtual

C#:

[DllImport("NOVA_API.dll", EntryPoint = "SendRequest")]
private static extern byte SendRequest(string xData, int DataLen);

In summation, the Clarion *CString can be converted to the .NET string type in DLLImport declarations.

Many thanks to those who responded. Here is an additional resource I used in my search, which I found very usefull: pinvoke.net

نصائح أخرى

In C# a long is always 64 bits. The Long in Clarion is 32 bits. Change the long parameters in your p/Invoke declaration to int's.

According to wikipedia clarion can uses some weird TopSpeed "double fast call" where they use 4 reg for parameters instead of two. If code is compiled using this calling convention it will be impossible to call directly from C#.

TopSpeed / Clarion / JPI The first four integer parameters are passed in registers eax, ebx, ecx and edx. Floating point parameters are passed on the floating point stack – registers st0, st1, st2, st3, st4, st5 and st6. Structure parameters are always passed on the stack. Additional parameters are passed on the stack after registers are exhausted. Integer values are returned in eax, pointers in edx and floating point types in st0.

If this is not the case then probably one of your parameters is not the right size otherwise you would be getting an AV instead of corrupt stack error.

Can also try setting the calling convention on the dllimport. In addition to "TOPSPEED" clarion also supports stdcall and cdecl but "TOPSPEED" is the default. Below is a link to a tutorial on interop with vb6 and clarion.

http://pisoft.ru/verstak/insider/cw_vb.htm

Have you tried char[]? I am not sure that it would work but it is worth a shot. (I'd post this as a comment but I don't have the rights)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top