What do "_in_" and "_in_opt_" mean in C++/CLI? - c++-cli

I'm fairly new to CLR, I'm reading the c++/CLI documentation for setWindowPos and the function is defined like so.
BOOL WINAPI SetWindowPos(
_In_ HWND hWnd,
_In_opt_ HWND hWndInsertAfter,
_In_ int X,
_In_ int Y,
_In_ int cx,
_In_ int cy,
_In_ UINT uFlags
);
I have experience in c++ so I understand that, for example, "HWND" is the data type and "hWnd" is the variable name.
But what are "_in_" and "_in_opt_"?
I'm guessing they're short for "input variables" or something.
It is mentioned in the documentation that the hWndInsertAfter is optional. Does this mean I can simply omit/not bother passing a variable to to this parameter in my function call if I don't need to?
e.g.
SetWindowPos(this,0,0,GetSystemMetrics(SM_CXMAXIMIZED),GetSystemMetrics(SM_CYMAXIMIZED),SWP_NOZORDER);
//Note that we're one parameter short here (the second is missing)
(This would be confusing to me, as I've seen it written in other places that C++ does not support optional parameters. Only default parameters and overloading)

This is part of Microsoft's Source-Code Annotation Language. _In_Opt_ means you may pass NULL.

Related

Call Library Function Node Error 1097

I'm pretty new to labview and I'm trying to use a Call Library Function Node to use a function from my library.
The function has the following prototype:
int function_name(int arg1, void* arg2, int* arg3, my_enum* arg4);
My call function nodes has 5 parameters, the return and the ones of the function that i have set in this way:
arg1, is a numeric I32;
arg2, is an array of U8 passed by value;
arg3, is a numeric I32 passed as a Pointer;
arg4, is a numeric I16 passed as a pointer;
My setup doesn't work, and i get an error 1097.
I'm pretty sure that the problem is with arg2, which is a pointer to a memory location in which the function will leave some data. How can I make it work?
I'm using LabView 2017, notice that arg2 and arg4 gets uploaded correctly.

Putting Function Pointers in a Perl6 NativeCall CStruct

Trying to interface with a C library that takes a struct with a bunch of pointers to functions it calls at various points.
something like this:
struct callbacks {
int (*foo)(int);
int (*bar)(int);
}
int set_callbacks(callbacks *cbs);
I can make my callbacks:
sub foo-callback(int32 --> int32) {...}
sub bar-callback(int32 --> int32) {...}
It would be cool if this worked:
class Callbacks is repr<CStruct>
{
has &.foo (int32 --> int32);
has &.bar (int32 --> int32);
}
but it doesn't. I'm trying to do something with:
class Callbacks is repr<CStruct>
{
has Pointer $.foo;
has Pointer $.bar;
}
and set those to nativecast(Pointer, &foo-callback) or some such, but I can't
seem to force them in there.
Is there any way to do this beyond writing a little C function that takes all the Perl 6 function pointers and plugging them in the structure in C?
I still can't find an official way to do this, but I figured out a work-around.
Declare a version of sprintf that takes a function pointer of the right type (so it will set up the calling shim correctly), but cheat and have sprintf just give me back the pointer as a number (%lld) I can stuff in the Pointer.
class Callbacks is repr<CStruct>
{
has Pointer $.foo;
has Pointer $.bar;
sub sprintf(Blob, Str, & (int32 --> int32) --> int32) is native {}
submethod BUILD(:&foo, :&bar)
{
my $buf = buf8.allocate(20);
my $len = sprintf($buf, "%lld", &foo);
$!foo := Pointer.new($buf.subbuf(^$len).decode.Int);
$len = sprintf($buf, "%lld", &bar);
$!bar := Pointer.new($buf.subbuf(^$len).decode.Int);
}
}
sub foo-callback(int32 $x --> int32) {...}
sub bar-callback(int32 $x --> int32) {...}
my $callbacks = Callbacks.new(foo => &foo-callback,
bar => &bar-callback);
If you have multiple callbacks with different signatures, just declare a sprintf for each C calling signature you need, e.g.:
sub sprintf-ii(Blob, Str, & (int32 --> int32) --> int32)
is native is symbol('sprintf') {}
sub sprintf-isi(Blob, Str, & (int32, Str --> int32) --> int32)
is native is symbol('sprintf') {}
and call the right sprintf-* for each callback pointer you need.
There is probably an easier way than going back and forth with the pointer to number to string to number to pointer, but this does the trick for now.

Only first character is passed in pinvoke string

I have a c++ dll that I am using using Pinvoke.
The method signature is as follow:
c++:
EXTERN_C BOOL std_call MyCppMethod(LPCSTR param1, LPCSTR param2);
C#:
[DllImport("MyDll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool MyCppMethod(
/*[MarshalAs(UnmanagedType.LPWStr)]*/ string param1,
/*[MarshalAs(UnmanagedType.LPWStr)]*/ string param2
);
for technical reasons I replaced the dll with a lib, and wrapped the lib with a dll that uses EXPORTS.def file and EXPORTS declaration to export the method from the lib.
Since I have dine that I see a weird behavior. instead of getting the string in the method implementation I get only the first character.
I had tried to replace the calling convention, to use marshalAs LPCWSTR, and also tried to replace the lpcstr in the c++ decleration with char*.
non of the above helped me to solve the problem and I still get only the first character.
Why this is happening and how can I solve this problem?
LPCSTR is a pointer to null-terminated array of char, and UnmanagedType.LPWStr is a pointer to null-terminated array of wchar_t. So there is a simple mis-match.
The reason why you only received a single character is that ASCII characters, when represented as two byte UTF-16 characters, have the ASCII value in one byte, and a zero in the other byte. When interpreted as null-terminated array of char, this is a string of length one. The zero byte is interpreted as the null-terminator.
You can fix it by changing either:
LPCSTR to LPCWSTR on the native side, or
UnmanagedType.LPWStr to UnmanagedType.LPStr on the managed side.
Frankly, to me it makes more sense to use Unicode these days so I would go for option 1. Indeed, since you specified CharSet.Unicode then there is no need for the MarshalAs at all. The code would look like this:
C++
BOOL std_call MyCppMethod(LPCWSTR param1, LPCWSTR param2);
C#
[DllImport("MyDll.dll", CharSet = CharSet.Unicode)]
public static extern bool MyCppMethod(string param1, string param2);
Note that I am also sceptical of your setting SetLastError to true. Does your function really call SetLastError?

A call to PInvoke function 'ABC' has unbalanced the stack.

I have a C# application (x86 .net 3.5 on Windows 7 vs2010) which call a C function
when I upgrade it to .net 4, I got the following message:
This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
C signature:
BOOL ABC( UDF_HANDLE handle, char* pQualifiedName )
//#define UDF_HANDLE void*
C# side:
[SecuritySafeCritical]
[DllImport(dllPath, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, ThrowOnUnmappableChar = true)]
internal static extern int ABC(
[In] IntPtr handle,
[MarshalAs(UnmanagedType.LPStr)] string qualifiedName);
Any help appreciated.
I redefined ABC first parameter to be same as the first parameter in the function.
The C++ code uses the cdecl calling convention. But you've specified stdcall in your p/invoke. Change that in the C# code and your two declarations will match.

Marshalling simple and complex datatypes to/from Object^% / void*

I guess this will be simple for C++/CLI gurus.
I am creating a wrapper which will expose high-performance C++ native classes to C# WinForms application.
Everything went fine with simple known objects and I could wrap also a callback function to delegate. But now I am a bit confused.
The native C++ class has a following method:
int GetProperty(int propId, void* propInOut)
At first I thought I could use void* as IntPtr, but then I found out that I need to access it from C#. So I thought about a wrapper method:
int GetProperty(int propId, Object^ propInOut)
but as I looked through the C++ source, I found out that the method needs to modify the objects. So obviously I need:
int GetProperty(int propId, Object^% propInOut)
Now I cannot pass Objects to native methods so I need to know how to treat them in the wrapper. As the caller should always know what kind of data he/she is passing/receiving, I declared a wrapper:
int GetProperty(int propId, int dataType, Object^% propInOut)
I guess, I can use it to pass reference and value types, for example, an int like this:
Object count = 100; // yeah, I know boxing is bad but this will not be real-time call anyway
myWrapper.GetProperty(Registry.PROP_SMTH, DATA_TYPE_INT, ref count);
I just added a bunch of dataType constants for all the data types I need:
DATA_TYPE_INT, DATA_TYPE_FLOAT, DATA_TYPE_STRING, DATA_TYPE_DESCRIPTOR, DATA_TYPE_BYTE_ARRAY
(DATA_TYPE_DESCRIPTOR is a simple struct with two fields: int Id and wstring Description - this type will be wrapped too, so I guess marshaling will be simple copying data back and forth; all the native strings are Unicode).
Now, the question is - how to implement the wrapper method for all these 5 types?
When I can just cast Object^% to something (is int, float safe to do that?) and pass to native method, when do I need to use pin_ptr and when I need some more complex marshaling to native and back?
int GetProperty(int propId, int dataType, Object^% propInOut)
{
if(dataType == DATA_TYPE_INT)
{
int* marshaledPropInOut = ???
int result = nativeObject->GetProperty(propId, (void*)marshaledPropInOut);
// need to do anything more?
return result;
}
else
if(dataType == DATA_TYPE_FLOAT)
{
float* marshaledPropInOut = ???
int result = nativeObject->GetProperty(propId, (void*)marshaledPropInOut);
// need to do anything more ?
return result;
}
else
if(dataType == DATA_TYPE_STRING)
{
// will pin_ptr be needed or it is enough with the tracking reference in the declaration?
// the pointers won't get stored anywhere in C++ later so I don't need AllocHGlobal
int result = nativeObject->GetProperty(propId, (void*)marshaledPropInOut);
// need to do anything more?
return result;
}
else
if(dataType == DATA_TYPE_BYTE_ARRAY)
{
// need to convert form managed byte[] to native char[] and back;
// user has already allocated byte[] so I can get the size of array somehow
return result;
}
else
if(dataType == DATA_TYPE_DESCRIPTOR)
{
// I guess I'll have to do a dumb copying between native and managed struct,
// the only problem is pinning of the string again before passing to the native
return result;
}
return -1;
}
P.S. Maybe there is a more elegant solution for wrapping this void* method with many possible datatypes?
It doesn't necessarily make sense to equate a C# object to a void*. There isn't any way to marshal arbitrary data. Even with an object, C# still knows what type it is underneath, and for marshaling to take place -- meaning a conversion from the C++ world to C# or vice-versa -- the type of data needs to be known. A void* is just a pointer to memory of a completely unknown type, so how would you convert it to an object, where the type has to be known?
If you have a limited number of types as you describe that could be passed in from the C# world, it is best to make several overloads in your C++/CLI code, each of which took one of those types, and then you can pin the type passed in (if necessary), convert it to a void*, pass that to your C++ function that takes a void*, and then marshal back as appropriate for the type.
You could implement a case statement as you listed, but then what do you do if you can't handle the type that was passed in? The person calling the function from C# has no way to know what types are acceptable and the compiler can't help you figure out that you did something wrong.