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).
Related
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.
I'm working on changing some Objective-C Code over to Swift, and I cannot figure out for the life of me how to take care of unsigned char arrays and bitwise operations in this specific instance of code.
Specifically, I'm working on converting the following Objective-C code (which deals with CoreBluetooth) to Swift:
unsigned char advertisementBytes[21] = {0};
[self.proximityUUID getUUIDBytes:(unsigned char *)&advertisementBytes];
advertisementBytes[16] = (unsigned char)(self.major >> 8);
advertisementBytes[17] = (unsigned char)(self.major & 255);
I've tried the following in Swift:
var advertisementBytes: CMutablePointer<CUnsignedChar>
self.proximityUUID.getUUIDBytes(advertisementBytes)
advertisementBytes[16] = (CUnsignedChar)(self.major >> 8)
The problems I'm running into are that getUUIDBytes in Swift seems to only take a CMutablePointer<CUnsignedChar> object as an argument, rather than an array of CUnsignedChars, so I have no idea how to do the later bitwise operations on advertisementBytes, as it seems it would need to be an unsignedChar array to do so.
Additionally, CMutablePointer<CUnsignedChar[21]> throws an error saying that fixed length arrays are not supported in CMutablePointers in Swift.
Could anyone please advise on potential work-arounds or solutions? Many thanks.
Have a look at Interacting with C APIs
Mostly this
C Mutable Pointers
When a function is declared as taking a CMutablePointer
argument, it can accept any of the following:
nil, which is passed as a null pointer
A CMutablePointer value
An in-out expression whose operand is a stored lvalue of type Type,
which is passed as the address of the lvalue
An in-out Type[] value,
which is passed as a pointer to the start of the array, and
lifetime-extended for the duration of the call
If you have declared a
function like this one:
SWIFT
func takesAMutablePointer(x: CMutablePointer<Float>) { /*...*/ } You
can call it in any of the following ways:
SWIFT
var x: Float = 0.0
var p: CMutablePointer<Float> = nil
var a: Float[] = [1.0, 2.0, 3.0]
takesAMutablePointer(nil)
takesAMutablePointer(p)
takesAMutablePointer(&x)
takesAMutablePointer(&a)
So you code becomes
var advertisementBytes = CUnsignedChar[]()
self.proximityUUID.getUUIDBytes(&advertisementBytes)
advertisementBytes[16] = CUnsignedChar(self.major >> 8)
I want to copy two dimensional arrays and I made this function but it caused a compilation error
void Cpy_2d_arr(unsigned char *from,unsigned char *to)
{
unsigned char col,row;
for (row=0;row<4;row++)
{
for(col=0;col<4;col++)
{
(*(*(to+row)+col)) = (*(*(from+row)+col));
}
}
}
The two dimensional arrays are
unsigned char arr[4][4] = {'7','8','9','-','4','5','6','*','1','2','3','-','c','0','=','+'};
the target is an array inside a struct with the same size
the errors are :
1- Error 8 expected 'unsigned char ' but argument is of type 'unsigned char ()[4]
2- Error 11 subscripted value is neither array nor pointer
3- Error 11 invalid type argument of unary '*' (have 'int')
char arr[4][4] = {'7','8','9','-','4','5','6','*','1','2','3','-','c','0','=','+'};
is an array of pointers
void Cpy_2d_arr(unsigned char *from,unsigned char *to)
receives an single pointer( e.g. to an array of chars).
the types of your parameters are not compatible, change it to
void Cpy_2d_arr(unsigned char from[4][4],unsigned char to[4][4])
it should work just fine
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.
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.