Use of THIS-> in C/C++ [closed] - objective-c

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm going through a tutorial on audio for the iphone and it uses C/C++. I'm not familiar with the use of THIS->. It seems to refer to a pointer to global variable. Here is the tutorial - iPhone Core Audio Part 3 – Audio Callback.
The statement I am trying to understand is the THIS-> part of the statement:
// Pass in a reference to the phase value, you have to keep track of this
// so that the sin resumes right where the last call left off
float phase = THIS->sinPhase;
The tutorial indicate that THIS-> is used to get a to access AudioController variables. It seems that sinPhase is global variable.
Please explain why "phase" reference is created instead of just referring directly to the global variable "sinPhase". Keep in mind I am an objective C programming trying to understand this C/C++ code.

In this example, THIS is not a reference to a global variable; it is defined above in the function, as a cast of the void pointer inRefCon:
static OSStatus renderInput(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
// Get a reference to the object that was passed with the callback
// In this case, the AudioController passed itself so
// that you can access its data.
AudioController *THIS = (AudioController*)inRefCon;
This is a fairly common pattern in C; in order to pass a callback in to some API, so that it can later call your code, you pass both a function pointer and a void pointer. The void pointer contains whatever data your function pointer will need to operate on. Within your callback, you will need to cast it back to a pointer to the actual type, so you can access the data within it. In this case, the author of the example is naming that cast pointer THIS, probably to make this look more object-oriented, even though this is just C and THIS has no special meaning.
You ask why they assign it to a local variable rather than just using THIS->sinPhase everywhere. There's no reason you couldn't use THIS->sinPhase everywhere; they likely just assigned it to a local variable phase to save on typing. There's a small chance that the optimizer could do a better job on a local variable than on one passed in via a pointer, because it can make more assumptions about the local variable (in particular, it can assume that no one else is updating it at the same time). So the loop might run slightly faster using a local variable, though I wouldn't be certain without testing; the most likely reason is just to save typing and make the code more readable.
Here's a simplified example of how a callback API like this works; hopefully this should make it easier to understand how a callback API works, without trying to understand the rest of what's going on in Core Audio at the same time. Let's say I want to write a function that will apply a callback to an integer 10 times. I might write:
int do_ten_times(int input, int (*callback)(int)) {
int value = input;
for (int i = 0; i < 10; ++i) {
value = callback(value);
}
return value;
}
Now I could call this with different functions, like the following add_one() or times_two():
int add_one(int x) {
return x + 1;
}
int times_two(int x) {
return x * 2;
}
result = do_ten_times(1, add_one);
result = do_ten_times(1, times_two);
But say I want to be able to add or multiply by different numbers; I could try writing one function for each number that you wanted to add or multiply by, but then you would run into a problem if the number wasn't fixed in the code, but was based on input. You can't write one function for each possible number; you are going to need to pass a value in. So let's add a value to our callbacks, and have do_ten_times() pass that value in:
int do_ten_times(int input, int (*callback)(int, int), int data) {
int value = input;
for (int i = 0; i < 10; ++i) {
value = callback(value, data);
}
return value;
}
int add(int x, int increment) {
return x + increment;
}
int times(int x, int multiplier) {
return x * multiplier;
}
result = do_ten_times(1, add, 3);
result = do_ten_times(1, times, 4);
But what if someone wants to write a function that varies by something other than an integer? For instance, what if you want to write a function that will add different numbers depending on whether the input is negative or positive? Now we need to pass two values in. Again, we could extend our interface to pass in two values; but we will eventually need to pass in more values, values of different types, and the like. We notice that do_ten_times really doesn't care about the type of the value we're passing in; it just needs to pass it to the callback, and the callback can interpret it however it likes. We can achieve this with a void pointer; the callback then casts that void pointer to the appropriate type to get the value out:
int do_ten_times(int input, int (*callback)(int, void *), void *data) {
int value = input;
for (int i = 0; i < 10; ++i) {
value = callback(value, data);
}
return value;
}
int add(int x, void *data) {
int increment = *(int *)data;
return x + increment;
}
int times(int x, void *data) {
int multiplier = *(int *)data;
return x * multiplier;
}
struct pos_neg {
int pos;
int neg;
};
int add_pos_neg(int x, void *data) {
struct pos_neg *increments = (struct pos_neg *)data;
if (x >= 0)
return x + increments->pos;
else
return x + increments->neg;
}
int i = 3;
result = do_ten_times(1, add, &i);
int m = 4;
result = do_ten_times(1, times, &m);
struct pos_neg pn = { 2, -2 };
result = do_ten_times(-1, add_pos_neg, &pn);
These are all, of course, toy examples. In the Core Audio case, the callback is used to generate a buffer of audio data; it is called every time the audio system needs to generate more data in order to keep playing smoothly. The information passed via the void *inRefCon is used to track how exactly where in the sine wave you have gotten to in the current buffer, so the next buffer can pick up where the last one left off.

If it's not declared in scope (i.e. local variable declared in that context), I see two options:
either it's a define, and it actually refers to the instance: #define THIS this.
either a global variable, as you suggested.
THIS doesn't have any inherent meaning in C++, so it can be either. Whichever it is though, it's pretty awful.
The reason it's copied in a different variable, in case it's a global, and not used directly, can be either for clarity or to not accidentally modify it.

Related

"SafeArray cannot be marshaled to this array type" error

I have a C++ COM local server and C# client. The server code:
// MyStruct as define in the _i.h file
typedef /* [uuid] */ DECLSPEC_UUID("...") struct MyStruct
{
SAFEARRAY * FormatData;
LONG aLong;
BOOL aBool;
} MyStruct;
// Server method being invoked
STDMETHODIMP CMyClass::Foo(MyStruct* StreamInfo, int* result)
{
long Length;
BYTE* Data;
GetData(Length, Data);
PackBytes(Length, Data, &(StreamInfo->FormatData));
}
PackBytes converts the BYTE array to SAFEARRAY. It is taken from this stackoverflow question. It sets the boundary & dimension of the SAFEARRAY.
The client code:
MyStruct myStruct;
int rc = obj.Foo(out myStruct);
Where MyStruct is imported from the COM assembly. it appears as
public struct MyStruct
{
public Array FormatData;
int aLong;
int aBool;
}
After running Foo appears the error "SafeArray cannot be marshaled to this array type because it has either nonzero lower bounds or more than one dimension" with additional remark "Make sure your array has the required number of dimensions".
When debugging the server code it seems Data is properly populated in FormatData: as can be seen in screen-shot below. cElements equals Length and the 18 data pieces are equal to the ones in Data.
Hard-coding Length = 1 did not help. Removing the PackByets call made the error disappear (other fields were passed ok). How can this be fixed?
The PackBytes method that you have referenced constructs a SAFEARRAY with lower bound of 1. Constructing it with a lower bound of zero may fix the problem:
SAFEARRAYBOUND bound{ count, 0 };

C++/CLI pin_ptr's usage in proper way

I am newbie of C++/CLI.
I already know that the pin_ptr's functionality is making GC not to learn to specified object.
now let me show you msdn's example.
https://msdn.microsoft.com/en-us//library/1dz8byfh.aspx
// pin_ptr_1.cpp
// compile with: /clr
using namespace System;
#define SIZE 10
#pragma unmanaged
// native function that initializes an array
void native_function(int* p) {
for(int i = 0 ; i < 10 ; i++)
p[i] = i;
}
#pragma managed
public ref class A {
private:
array<int>^ arr; // CLR integer array
public:
A() {
arr = gcnew array<int>(SIZE);
}
void load() {
pin_ptr<int> p = &arr[0]; // pin pointer to first element in arr
int* np = p; // pointer to the first element in arr
native_function(np); // pass pointer to native function
}
int sum() {
int total = 0;
for (int i = 0 ; i < SIZE ; i++)
total += arr[i];
return total;
}
};
int main() {
A^ a = gcnew A;
a->load(); // initialize managed array using the native function
Console::WriteLine(a->sum());
}
hear is the question.
Isn't it okay, the passed object(arr) not pinned ?
because the unmanaged code(native_function) is sync operation and finished before the C++/CLI code (load)
is there any chance the gc destory arr, even though the main logic is running?
(I think A is main's stack variable and arr is A's member variable, so while running main, it should visible)
if so, how can we guarantee that the A is there before invoking load?
(only while not running in native-code?)
int main() {
A^ a = gcnew A;
// I Think A or arr can be destroyed in here, if it is able to be destroyed in native_function.
a->load();
...
}
Thanks, in advance.
The problem that is solved by pinning a pointer is not a normal concurrency issue. It might be true that no other thread will preempt the execution of your native function. However, you have to count in the garbage collector, which might kick in whenever the .NET runtime sees fit. For instance, the system might run low on memory, so the runtime decides to collect disposed objects. This might happen while your native function executes, and the garbage collector might relocate the array it is using, so the pointer you passed in isn't valid anymore.
The golden rule of thumb is to pin ALL array pointers and ALL string pointers before passing them to a native function. ALWAYS. Don't think about it, just do it as a rule. Your code might work fine for a long time without pinning, but one day bad luck will strike you just when it's most annoying.

What is this Objective C code doing

I am a developer in C-like languages (Java/JavaScript/C#) and I am attempting to convert some Objective-C code into Java.
For the most part, it is relatively straightforward but I have hit a stumbling block with the following bit of code:
typedef struct {
char *PAGE_AREA_ONE;
char *PAGE_AREA_TWO;
char *PAGE_AREA_THREE;
} CODES;
- (CODES*) getOpCode {
CODES *result = NULL;
result = malloc(sizeof(CODES));
result->PAGE_AREA_ONE = "\x1b\x1b\x1b";
result->PAGE_AREA_TWO = "\x2d\x2d\x2d";
result->PAGE_AREA_THREE = "\x40\x40";
return result;
}
What would the Java equivalent of this be? From what I can tell in other areas of the code, it is being used to store constants. But I am not 100% certain.
Thanks.
The typedef is just creating a structure that contains three string properties. The getOpCode method is apparently trying to create a new structure and assign values to those three properties. C# code would be:
public class Codes
{
public string PageAreaOne;
public string PageAreaTwo;
public string PageAreaThree;
}
public Codes GetCodes()
{
Codes result = new Codes();
result.PageAreaOne = "\x1b\x1b\x1b"; // three ESC characters
result.PageAreaTwo = "---";
result.PageAreaThree = "##";
return result;
}
The code in question is allocating a block of memory that the size of the CODES structure, filling it with some data, and returning a pointer to the new block. The data is apparently some operation codes (that is, instructions) for something, so perhaps the data is being sent to some other device where the instructions will be executed.

Static analysis: Passing pointer to uninitialized data

In the past, we've had some trouble with uninitialized data in C-code. I've tried two different static code analysis tools on the code example below. None of them complain about passing a pointer to uninitialized data. Are you aware of any tool that would catch this?
Thank you in advance!
static int useByVal(const int int_val)
{
return int_val + 1;
}
static void useByRef(int* const int_ptr)
{
if (int_ptr != (void*)0)
{
(*int_ptr)++;
}
}
int main(void)
{
int i;
int k;
/*** GOOD: The tool detects error: Using value of uninitialized automatic object 'i' */
i = useByVal(i);
/*** BAD: The tool does not catch uninitialized object 'k' when passed by reference */
useByRef(&k);
/*** BAD: Since call to 'useByRef(&k)', the tool now consider 'k' as initialized */
return i+k;
}
No I'm not aware if any tool that would catch that. The reason is that they usually analyze on a function-by-function basis. In other words, while analyzing main tools would not analyze useByVal or useByRef, but make reasonable assumptions about them (like they expect an uninitialized object).
Additionally, if they did generate messages in this case, then you would need to add comments / pragmas to remove them and say "this usage is OK; don't emit a message any more". Because of the nature and frequency of pointer-passing, your program would be full of them.
Better implement some dynamic technique and catch the problem during testing.

Is there a way to wrap an ObjectiveC block into function pointer?

I have to provide a C-style callback for a specific C library in an iOS app. The callback has no void *userData or something similar. So I am not able to loop in a context. I'd like to avoid introducing a global context to solve this. An ideal solution would be an Objective-C block.
My question: Is there a way to 'cast' a block into a function pointer or to wrap/cloak it somehow?
Technically, you could get access to a function pointer for the block. But it's totally unsafe to do so, so I certainly don't recommend it. To see how, consider the following example:
#import <Foundation/Foundation.h>
struct Block_layout {
void *isa;
int flags;
int reserved;
void (*invoke)(void *, ...);
struct Block_descriptor *descriptor;
};
int main(int argc, char *argv[]) {
#autoreleasepool {
// Block that doesn't take or return anything
void(^block)() = ^{
NSLog(#"Howdy %i", argc);
};
// Cast to a struct with the same memory layout
struct Block_layout *blockStr = (struct Block_layout *)(__bridge void *)block;
// Now do same as `block()':
blockStr->invoke(blockStr);
// Block that takes an int and returns an int
int(^returnBlock)(int) = ^int(int a){
return a;
};
// Cast to a struct with the same memory layout
struct Block_layout *blockStr2 = (struct Block_layout *)(__bridge void *)returnBlock;
// Now do same as `returnBlock(argc)':
int ret = ((int(*)(void*, int a, ...))(blockStr2->invoke))(blockStr2, argc);
NSLog(#"ret = %i", ret);
}
}
Running that yields:
Howdy 1
ret = 1
Which is what we'd expect from purely executing those blocks directly with block(). So, you could use invoke as your function pointer.
But as I say, this is totally unsafe. Don't actually use this!
If you want to see a write-up of a way to do what you're asking, then check this out:
http://www.mikeash.com/pyblog/friday-qa-2010-02-12-trampolining-blocks-with-mutable-code.html
It's just a great write-up of what you would need to do to get this to work. Sadly, it's never going to work on iOS though (since you need to mark a page as executable which you're not allowed to do within your app's sandbox). But nevertheless, a great article.
If your block needs context information, and the callback does not offer any context, I'm afraid the answer is a clear no. Blocks have to store context information somewhere, so you will never be able to cast such a block into a no-arguments function pointer.
A carefully designed global variable approach is probably the best solution in this case.
MABlockClosure can do exactly this. But it may be overkill for whatever you need.
I know this has been solved but, for interested parties, I have another solution.
Remap the entire function to a new address space. The new resulting address can be used as a key to the required data.
#import <mach/mach_init.h>
#import <mach/vm_map.h>
void *remap_address(void* address, int page_count)
{
vm_address_t source_address = (vm_address_t) address;
vm_address_t source_page = source_address & ~PAGE_MASK;
vm_address_t destination_page = 0;
vm_prot_t cur_prot;
vm_prot_t max_prot;
kern_return_t status = vm_remap(mach_task_self(),
&destination_page,
PAGE_SIZE*(page_count ? page_count : 4),
0,
VM_FLAGS_ANYWHERE,
mach_task_self(),
source_page,
FALSE,
&cur_prot,
&max_prot,
VM_INHERIT_NONE);
if (status != KERN_SUCCESS)
{
return NULL;
}
vm_address_t destination_address = destination_page | (source_address & PAGE_MASK);
return (void*) destination_address;
}
Remember to handle pages that aren't required anymore and note that it takes a lot more memory per invocation than MABlockClosure.
(Tested on iOS)