How to I declare "LPTSTR" for Raku NativeCall? - raku

Raku/Perl6
Windows
I am trying to code a Raku Native call to a C functions that uses a "LPTSTR". How do I declare that? Something like constant DWORD := int32; but for LPTSTR?
If it helps, I found this description: "LPTSTR is a [long] pointer to a (non-const) TCHAR string" and "LPTSTR: null-terminated string of TCHAR (Long Pointer)"
"LPTSTR" comes from "LPWSTR lpBuffer,"

LP = (long) pointer, TSTR = either a wide string if UNICODE is defined, or an 8-bit string if not. So it's either a wchar_t * or unsigned char *. Determining which of these is in effect for the library you're using is probably quite difficult from Raku-space.

Related

How do I convert array<unsigned char> to an unsigned char[]?

In a CLR project I have the output of AesManaged class as a 16 byte array
array<unsigned char>^ result = msEncrypt->ToArray();
However I need to convert this to an array of type unsigned char defined like this
unsigned char buff[16];
EDIT: I did try this but its giving error (no method signature with those parameters, although there is one)
System::Runtime::InteropServices::Marshal::Copy(result, 0, buff, 16);
And this one
buff = reinterpret_cast<unsigned char>(&result);
But the error is Expression must be a modifiable lvalue
According to this MSDN documentation I used this and it appears to work
pin_ptr<unsigned char>buff = &result[0];

XOR reverse a string in objective-c get an error

I want to use the following code to reverse a char * type string in objective-c:
- (char *)reverseString:(char *)aString
{
unsigned long length = strlen(aString);
int end = length - 1;
int start = 0;
while (start < end) {
aString[start] ^= aString[end];
aString[end] ^= aString[start];
aString[start] ^= aString[end];
++start;
--end;
}
return aString;
}
But I got an error EXC_BAD_ACCESS at this line
aString[start] ^= aString[end]
I googled and found people said I can't modify a literal string because it is readonly. I am new to C so I wonder what simple data type (no object) I can use in this example? I get the same error when I use (char []) aString to replace (char *) aString.
I assume you're calling this like
[myObj reverseString:"foobar"];
The string "foobar" here is a constant literal string. Its type should be const char *, but because C is braindead, it's char *. But it's still constant, so any attempt to modify it is going to fail.
Declaring the method as taking char[] actually makes no difference whatsoever. When used as a parameter type, char[] is identical to char*.
You have two choices here. The first is to duplicate the string before passing it to the method. The second is to change the method to not modify its input string at all but instead to return a new string as output. Both can be accomplished using strdup(). Just remember that the string returned from strdup() will need to be free()'d later.

PInvoke from Fortran to C#

I want to import a function from a Fortran compiled library the signature of the function form for that I have access is in c:
typedef void (__stdcall *fp_SUBLTdllTYPE)(double &,double *,double &,long &,char*,long );
My C# code is as follows:
//(long &,char*,char*,char*,long &,char*,long ,long ,long ,long );
[DllImport(#"C:\Program Files\REFPROP\refprop.dll",
CallingConvention=CallingConvention.StdCall,
CharSet = CharSet.Auto,
EntryPoint = "SETUPdll")
]
public static extern void Setup([In] long nc,[In]
[MarshalAs(UnmanagedType.LPStr)] StringBuilder hfiles,
[In] [MarshalAs(UnmanagedType.LPStr)] StringBuilder hfmix,
[In] [MarshalAs(UnmanagedType.LPStr)] StringBuilder hrf,
[In,Out] long ierr, [Out] [MarshalAs(UnmanagedType.LPStr)] StringBuilder herr,long l1, long l2, long l3,long l4);
and the fortran definition is:
subroutine SETUP (nc,hfiles,hfmix,hrf,ierr,herr)
implicit double precision (a-h,o-z)
implicit integer (i-k,m,n)
implicit logical (l)
c
cDEC$ ATTRIBUTES DLLEXPORT :: SETUP
c dll_export SETUP
c
parameter (ncmax=20) !max number of components in mixture
parameter (nrefmx=10) !max number of fluids for transport ECS
parameter (n0=-ncmax-nrefmx,nx=ncmax)
parameter (nrf0=n0) !lower limit for transport ref fluid arrays
parameter (nrefluids=4) ! numb
the problem is that I do not have access to a Fortran compiller and my knolege of fortran is almost zero.
When I call the function from C# code:
long ierr=0;
long i = 2;
StringBuilder herr=new StringBuilder("");
Setup(i, new StringBuilder("R410a.mix"), new StringBuilder("hmx.bnc"), new StringBuilder("DEF"), ierr, herr, refpropcharlength * ncmax, refpropcharlength,
lengthofreference, errormessagelength);
I get the following error:
Attempted to read or write protected memory. This is often an
indication that other memory is corrupt.
Can anyone help me?
It seems incorrect to pass StringBuilder objects when you want a string. As a starting point I would try things like passing herr.ToString() or just build Strings to begin with instead of StringBuilder(s).

Compilation Errors on .at(i) but not on [i]

Why is it that:
char SourceChar = Text.c_str()[Index];
compiles, but
char SourceChar = Text.c_str().at(Index);
does not? Is there a workaround to this?
Text.c_str() returns a 'const char *' which is a C type, so it's not an object. You can only access it's value with Text[i] or *(Text + i).
If you want to access the i-th character in a more OOP manner you could use Text[i] or Text.at(i).

Arithmetic with pointer types/

Some examples of adding and subtracting similarly typed pointers, using numeric and character pointers please. Using C.
Thanks.
You can check this to know about pointer arithmetic
Here's a practical example which extracts a single character from a C string:
char charAt( char *str, size_t idx) {
if (idx > strlen (str))
return '\0';
return *(str+idx);
}
Or another, which swaps an integer in an array with the one immediately before it (with no range checking):
void swapInts( int *base, size_t idx) {
tmp = *(base+idx);
*(base+idx) = *(base+idx-1);
*(base+idx-1) = tmp;
}
In both these cases, *(pointer+offset) is identical to pointer[offfset] but using pointer arithmetic instead of array offsets:
*(str+idx) -> str[idx]
*(base+idx) -> base[idx]
*(base+idx-1] -> base[idx-1]
Warning: Don't use these verbatim in your homework, have a think about them then write your own. If you copy them verbatim, you will almost certainly be failed since your educators no doubt watch these sites as well.