Following is a self referential struct from C++
typedef struct _FCV
{
unsigned long ulID;
unsigned long ulVersion;
unsigned long ulStatus;
unsigned long ulSize;
struct _FCV* pNext;
} FCV;
I need to use PInvoke to translate to C# struct,
What is the "pNext" i should declare?
Thank you.
You have perhaps reached the point where p/invoke is not the best tool for the job. The complexity here may make a C++/CLI layer a more attractive option.
With p/invoke you'd need to declare the pNext field as IntPtr. Then you'd need to populate one instance of the struct for each item in the linked list. Finally you'd need to walk through the list assigning to pNext. That will require you to pin each struct with GCHandle.Alloc and then get the pinned address with AddrOfPinnedObject. Once the call has been made you then need to destroy all the GCHandle objects to un-pin the structs.
So it's possible to do, but the code may be rather unwieldy, and may not be particularly efficient. You should seriously consider C++/CLI instead.
Related
Here's an interesting one for the objective-C gurus out there...
Is there a way to declare an objective-C block typedef that contains an argument of that typedef?
typedef BOOL (^SSCellAction) ( UITableViewController* inTVC, SSCellAction inChainedAction );
The idea is that I wanted to used chained menu action system that allows a chain of work/response to occur (usually 1-3 items). When the last action invokes, it passes nil for inChainedAction. Since this seems relatively trivial to imagine, I'll be dammed if I can't figure out how to declare it without llvm saying no. :)
rmaddy's comment is correct. Just as in C, a typedef cannot use itself. Basically, a typedef does not make a real type, but just makes an alias that the compiler expands out at compile-time. It is always possible to manually expand all typedefs in your program yourself (which is sometimes an instructive exercise), so that your program is written without typedefs. However, a recursive typedef cannot be expanded.
Some possible workarounds:
Use id as the parameter type, and cast back into the right type inside the block. This loses type safety.
Or, use a struct type of one member, the block. A struct is a real type, so it can be used within its definition. The downside of this is that you explicitly "wrap" the block into the struct type to pass it, and explicitly "unwrap" the struct into the block by accessing the field when you need to call it. This way is type-safe.
I have an unmanaged code with a fixed struct in memory, i need to read and write the struct from the managed side; the application is a real-time application and i cannot afford the struct's marshalling every time i need it, so i think is better to work in an unsafe context(for performance) and directy handle the pointer.
If i have this signature:
public static extern IntPtr COLM104_GetGlobalConf();
and my pointer is a RuntimeDescriptor*, can i store directly store the RuntimeDescriptor* as an object's field or i must keep the pointer in an IntPtr and every time i need it i should do:
(RuntimeDescriptor*)pointerField.ToPointer()
and last thing, can i directly change the p/invoke signature with:
public static extern RuntimeDescriptor* COLM104_GetGlobalConf();
Any help will be apreciated.
You can declare an unsafe member of type RuntimeDescriptor*. And you can declare the return value of your p/invoke to be of type RuntimeDescriptor*.
However, it doesn't really gain you any performance over a cast to RuntimeDescriptor*. Certainly with optimisations enabled, the compiler doesn't need to emit any actual code to perform the cast. However, if you are going down the route of using unsafe code then it's cleaner to be all-in. Declaring the member and return type to be RuntimeDescriptor* makes your program easier to read.
FWIW, there's no need for the call ToPointer() in the code in your question. You can write that cast like this:
(RuntimeDescriptor*)pointerField
I realize 99% of you think "what the h***…" But please help me to get my head around the this concept of using pointers. I'm sure my specific question would help lots of newbies.
I understand what pointers ARE and that they are a reference to an adress in memory and that by using the (*) operator you can get the value in that address.
Let's say:
int counter = 10;
int *somePointer = &counter;
Now I have the address in memory of counter, and I can indirectly point to its value by doing this:
int x = *somePointer;
Which makes x = 10, right?
But this is the most basic example, and for this case I could use int x = counter; and get that value, so please explain why pointers really are such an important thing in Objective-C and some other languages... in what case would only a pointer make sense?
Appreciate it.
Objective-C has pointers because it is an evolution of C, which used pointers extensively. The advantage of a pointer in an object-oriented language like Objective-C is that after you create an object, you can pass around a pointer to the object instead of passing around the object itself. In other words, if you have some object that takes up a large amount of storage space, passing around a pointer is a lot more memory-efficient than passing around a copy of the object itself. This may not be noticeable in simple cases when you’re only dealing with primitive types like ints, but when you start dealing with more complex objects the memory and time savings are enormous.
More importantly, pointers make it much easier for different parts of your code to talk to each other. If variables could only be passed to functions “by value” instead of “by reference” (which is what happens when you use pointers), then functions could never alter their inputs. They could only change the state of your program by either returning a value or by changing a global variable—the overuse of which generally leads to sloppy, unorganized code.
Here’s a concrete example. Suppose you have an Objective-C method that will parse a JSON string and return an NSDictionary:
+ (NSDictionary *)parseJsonString:(NSString *)json
error:(NSError **)error;
The method will do the parsing and return an NSDictionary if everything goes okay. But what if there’s some problem with the input string? We want a way to indicate to the user (or at least to the programmer) what happened, so we have a pointer to a pointer to an NSError, which will contain that information. If our method fails (probably returning nil), we can dereference the error parameter to see what went wrong. What we’ve effectively done is to give our method two different kinds of return values: usually, it will return an NSDictionary, but it could also return an NSError.
If you want to read more about this, you may have better luck searching for “pointers in C” rather than “pointers in Objective-C”; pointers are of course used extensively in Objective-C, but all of the underlying machinery is identical to that of C itself.
What is the biggest advantage of using pointers in ObjectiveC
I'd say the biggest advantage is that you can use Objective-C at all - all Objective-C objects are pointers are accessed using pointers (the compiler and the runtime won't let you create objects statically), so you wouldn't get any further without them...
Item:
What if I told you to write me a program that would maintain a set of counters, but the number of counters would be entered by the user when he started the program. We code this with an array of integers allocated on the heap.
int *counters = malloc(numOfCounters * sizeof(int));
Malloc works with memory directly, so it by nature returns a pointer. All Objective-C objects are heap-allocated with malloc, so these are always pointers.
Item:
What if I told you to write me a function that read a file, and then ran another function when it was done. However, this other function was unknown and would be added by other people, people I didn't even know.
For this we have the "callback". You'd write a function that looked like this:
int ReadAndCallBack(FILE *fileToRead, int numBytes, int whence, void(*callback)(char *));
That last argument is a pointer to a function. When someone calls the function you've written, they do something like this:
void MyDataFunction(char *dataToProcess);
ReadAndCallBack(myFile, 1024, 0, MyDataFunction);
Item:
Passing a pointer as a function argument is the most common way of returning multiple values from a function. In the Carbon libraries on OSX, almost all of the library functions return an error status, which poses a problem if a library function has to return something useful to the programmer. So you pass the address where you'd like the function to hand information back to you...
int size = 0;
int error = GetFileSize(afilePath,&size);
If the function call returns an error, it is in error, if there was no error, error will probably be zero and size will contain what we need.
The biggest advantage of pointers in Objective-C, or in any language with dynamic allocation, is that your program can handle more items than the names that you invent in your source code.
I'm calling a C method which returns a pointer or 'handle' to a resource. I just need to hold the void* in order to pass it in again later.
In .NET, I might use IntPtr. The only different between IntPtr and just an int--other than making the pointer a more strongly typed variable--is that IntPtr is automatically the size of the platform (32 or 64 bits). I'm looking for the same thing in Objective-C.
Is there some equivalent way to wrap a pointer in Objective-C?
Have you looked at NSValue's + (NSValue *)valueWithPointer:(const void *)aPointer?
Since Objective-C is a superset of C, you can simply use void *.
I have a game object which processed in two completely different places. In Contact Listener i check some conditions and if they occur i must save one or more portions of complex data. So i decided to use struct. For example:
struct SomeStruct
{
int value1;
int value2;
CGPoint value3;
b2Vec2 value4;
};
typedef SomeStruct SomeStruct;
In Game Scene i go through all game objects and if its the stack/array not empty, do some stuff and wipe it.
In Contact Listener it repeats from the beginning.
I must use this architecture because of strict order of execution (method must be called after other methods).
I suspect that i need something like vector or NSMutableArray (i think it will not work with struct), so vector may the the only way.
But don't understand how to achieve it. May you help me with some code/pseudocode or link to the book/article where i can found a solution?
Cocoa provides NSValue class for that purpose:
This creates an object that you can add to NSMutableArray:
NSValue *someObj = [NSValue valueWithBytes:&myStruct objCType:#encode(SomeStruct)];
You can use [someObj pointerValue] to access a void* representing the address of the structure that you put in NSValue.
There is a lot of solutions for this problem.
Don't use struct. An obj-c class is practically the same thing as a struct.
Use CFArray (CFArrayCreateMutable) and put it there as a pointer.
Use a C++ class with STL vector.
Use a C array (SomeStruct[]) and increase its length when you need it.
Use a classic implementation of a stack, with a linked list (every struct has a pointer to the next value).