What is the Objective-C data type to hold a void*/pointer? - objective-c

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 *.

Related

Converting PInvoke call to C++/CLI

My C++ DLL has function:
void allocate(double *&arr_not_allocated, UINT &arrayCount);
Normally, I pass into C++ from C# with:
allocate(out IntPtr arr_not_allocated, ref uint arrayCount)
I am just wondering what would be the equivalent call into C++ using C++/CLI instead of the above C#?
I should also note that I have no desire to hold the allocated array in managed memory(only in unmanaged), so I do not care to Marshal any structures on the managed side.
I just want to get the native pointer back from C++ and possibly pass the unmanaged array's address back to C++ in the future. So that is why I was using IntPtr in the past with P/Invoke.
Thanks!
In C++, pass by reference is completely transparent at the caller site. It doesn't distinguish between by-reference parameters used for input, output, or both. But it also does not permit variable declarations inside a function call, so you must declare those in advance. Final code is quite simple:
double* arr_not_allocated;
UINT arrayCount = whatever;
allocate(arr_not_allocated, arrayCount);
/* now both arrayCount and arr_not_allocated have been updated by the function */
If you don't have an import library, you may have to use LoadLibrary() and pass the resulting handle to GetProcAddress. The result of GetProcAddress gets cast to the correct function pointer type, i.e. typedef void (*allocate_fnptr)(double*&, UINT&);
I didn't include a calling convention, because your question didn't specify one. But you may need to throw a __cdecl or __stdcall into the function pointer type.

PInvoke of self referential struct from C++

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.

P/Invoke Unmanaged Pointer, as IntPtr or as void*

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

Is Objective-C pass-by-value or pass-by-reference?

Since we always use pointers to define variables, I was wondering if Objective-C is "pass by value", since like Java, the actual value would be passed by using its reference.
However, since it seems to be built up on top of C, would it have all the functionality of C?
C does not support pass-by-reference and Objective-C, being a strict superset of C doesn't either.
In C (and Objective-C) you can simulate pass-by-reference by passing a pointer, but it's important to remember that you're still technically passing a value, which happens to be a the value of a pointer.
So, in Objective-C (and C, for the matter) there is no concept of reference as intended in other languages (such as C++ or Java).
This can be confusing, so let me try to be clearer (I'll use plain C, but - again - it doesn't change in Objective-C)
void increment(int *x) {
*x++;
}
int i = 42;
increment(&i); // <--- this is NOT pass-by-reference.
// we're passing the value of a pointer to i
On the other hand in C++ we could do
void increment(int &x) {
x++;
}
int i = 41;
increment(i); // <--- this IS pass-by-reference
// doesn't compile in C (nor in Objective-C)
It is a strict superset of C.
It does the same as C.
It's one reason all Objects are actually pointers to structs.

How are objects passed and returned in Objective-C?

In Java, I can easily pass data using (ObjectA)objB. How can I do the similar things in Objective C? Also, why the Objective C can't return an Object, but only can return the id only? I do -(MyObj)returnMyObject{ }, but the Xcode warning me that I can't use the MyObj, but I can return the id..... -(id) returnMyObject {}.
The underlying model of Java and Apple's Objective C objects is really the same both have all objects on the heap and are accessed via pointers.
The difference is in Java the pointers are hidden so (ObjectA)objB is a pointer to data of type ObjectA. In Objective C the pointer is explicit and you need to say (MyObj*)returnMyObject{ }
id is a pointer to an object (so is an exception in that the pointer is implicit like Java)
As Mark has already pointed out; all Objective-C objects require the * at the end; it's always NSString *aString, never NSString aString.
This applies to casts as well; so you would have to do (MyObj *)anObject. Note, however, that the cast doesn't actually do anything, it's merely there as a hint for the compiler.