Is it possible to call a function by name in Objective C? For instance, if I know the name of a function ("foo"), is there any way I can get the pointer to the function using that name and call it? I stumbled across a similar question for python here and it seems it is possible there. I want to take the name of a function as input from the user and call the function. This function does not have to take any arguments.
For Objective-C methods, you can use performSelector… or NSInvocation, e.g.
NSString *methodName = #"doSomething";
[someObj performSelector:NSSelectorFromString(methodName)];
For C functions in dynamic libraries, you can use dlsym(), e.g.
void *dlhandle = dlopen("libsomething.dylib", RTLD_LOCAL);
void (*function)(void) = dlsym(dlhandle, "doSomething");
if (function) {
function();
}
For C functions that were statically linked, not in general. If the corresponding symbol hasn’t been stripped from the binary, you can use dlsym(), e.g.
void (*function)(void) = dlsym(RTLD_SELF, "doSomething");
if (function) {
function();
}
Update: ThomasW wrote a comment pointing to a related question, with an answer by dreamlax which, in turn, contains a link to the POSIX page about dlsym. In that answer, dreamlax notes the following with regard to converting a value returned by dlsym() to a function pointer variable:
The C standard does not actually define behaviour for converting to and from function pointers. Explanations vary as to why; the most common being that not all architectures implement function pointers as simple pointers to data. On some architectures, functions may reside in an entirely different segment of memory that is unaddressable using a pointer to void.
With this in mind, the calls above to dlsym() and the desired function can be made more portable as follows:
void (*function)(void);
*(void **)(&function) = dlsym(dlhandle, "doSomething");
if (function) {
(*function)();
}
Related
I've read Rafael's article and am now doing awful, terrible things with JavaConstant.Dynamic. Mostly I'm getting a feel for how it works.
As part of these horrid experiments, I am turning an array of non-constant things into an array of JavaConstants. Then I'm invoking JavaConstant.Dynamic.ofInvocation(SOME_METHOD_THAT_ACCEPTS_A_VARARGS_OF_THINGS, javaConstantsArray).
So, for example, something like this:
static final JavaConstant toJavaConstant(final Glorp[] glorps) {
final JavaConstant[] javaConstants = new JavaConstant[glorps.length];
for (int i = 0; i < javaConstants.length; i++) {
javaConstants[i] = toJavaConstant(glorps[i]); // another version of this method that works on scalars
}
return JavaConstant.Dynamic.ofInvocation(SOME_METHOD_THAT_ACCEPTS_A_VARARGS_OF_THINGS, javaConstants);
}
ByteBuddy is telling me in the ofInvocation call that one of the JavaConstants in the varargs array I've passed it is not assignable to the parameter type of the SOME_METHOD_THAT_ACCEPTS_A_VARARGS_OF_THINGS. I can understand this, because strictly speaking a variable arity method accepts an array as its last parameter, and a JavaConstant is not an array. But given that the SOME_METHOD_THAT_ACCEPTS_A_VARARGS_OF_THINGS is ultimately resolved via the MethodHandle machinery with all of its argument adaptation and spreading tricks, I wonder: is this proactive assignability check "too much"? Should ByteBuddy take into account the varargs nature of the bootstrap method? Is there some other way to create an array or a list of an arbitrary number of scalar constants as a constant itself?
Yes, this was a bug and it will be fixed in Byte Buddy 1.10.18. Thanks for the patch!
Can I call a function from LabVIEW that is at certain ordinal in some DLL, while the ordinal is determined at run-time?
I'm also interested if there is something similar to function pointers, like in 'C' language, which hold some dynamic function address?
If your intention is to call function by address, you will have to develop a wrapper in C by compiling a DLL from a code like that:
typedef int (*real_func_type)(int);
int wrapper(size_t address, int param1)
{
return ((real_func_type)address)(param1);
}
where real function proto is
int real_func(int param);
If your second question is whether LabVIEW has something similar to a function pointer, then the answer is that the closest thing is a VI reference. There are different types of VI references and different ways of creating and using them, so you would need to read up on that.
In any case, VI references are purely a LabVIEW construct. There's no mechanism for interacting with C function pointers directly and you can't create a function pointer to a VI and give that to the DLL function. For something like that you would also need some wrappers.
In your block diagram, create a case structure that takes your ordinal value. In each frame of the case structure, invoke the appropriate function from the DLL.
If you take this method call for instance(from other post)
- (int)methodName:(int)arg1 withArg2:(int)arg2
{
// Do something crazy!
return someInt;
}
Is withArg2 actually ever used for anything inside this method ?
withArg2 is part of the method name (it is usually written without arguments as methodName:withArg2: if you want to refer to the method in the documentation), so no, it is not used for anything inside the method.
As Tamás points out, withArg2 is part of the method name. If you write a function with the exact same name in C, it will look like this:
int methodNamewithArg2(int arg1, int arg2)
{
// Do something crazy!
return someInt;
}
Coming from other programming languages, the Objective-C syntax at first might appear weird, but after a while you will start to understand how it makes your whole code more expressive. If you see the following C++ function call:
anObject.subString("foobar", 2, 3, true);
and compare it to a similar Objective-C method invocation
[anObject subString:"foobar" startingAtCharacter:2 numberOfCharacters:3 makeResultUpperCase:YES];
it should become clear what I mean. The example may be contrived, but the point is to show that embedding the meaning of the next parameter into the method name allows to write very readable code. Even if you choose horrible variable names or use literals (as in the example above), you will still be able to make sense of the code without having to look up the method documentation.
You would call this method as follows:
int i=[self methodName:arg1 withArg2:arg2];
This is just iOs's way of making the code easier to read.
I've been using std::unique_ptr to store some COM resources, and provided a custom deleter function. However, many of the COM functions want pointer-to-pointer. Right now, I'm using the implementation detail of _Myptr, in my compiler. Is it going to break unique_ptr to be accessing this data member directly, or should I store a gajillion temporary pointers to construct unique_ptr rvalues from?
COM objects are reference-countable by their nature, so you shouldn't use anything except reference-counting smart pointers like ATL::CComPtr or _com_ptr_t even if it seems inappropriate for your usecase (I fully understand your concerns, I just think you assign too much weight to them). Both classes are designed to be used in all valid scenarios that arise when COM objects are used, including obtaining the pointer-to-pointer. Yes, that's a bit too much functionality, but if you don't expect any specific negative consequences you can't tolerate you should just use those classes - they are designed exactly for this purpose.
I've had to tackle the same problem not too long ago, and I came up with two different solutions:
The first was a simple wrapper that encapsulated a 'writeable' pointer and could be std::moved into my smart pointer. This is just a little more convenient that using the temp pointers you are mentioning, since you cannot define the type directly at the call-site.
Therefore, I didn't stick with that. So what I did was a Retrieve helper-function that would get the COM function and return my smart-pointer (and do all the temporary pointer stuff internally). Now this trivially works with free-functions that only have a single T** parameter. If you want to use this on something more complex, you can just pass in the call via std::bind and only leave the pointer-to-be-returned free.
I know that this is not directly what you're asking, but I think it's a neat solution to the problem you're having.
As a side note, I'd prefer boost's intrusive_ptr instead of std::unique_ptr, but that's a matter of taste, as always.
Edit: Here's some sample code that's transferred from my version using boost::intrusive_ptr (so it might not work out-of-the box with unique_ptr)
template <class T, class PtrType, class PtrDel>
HRESULT retrieve(T func, std::unique_ptr<PtrType, PtrDel>& ptr)
{
ElementType* raw_ptr=nullptr;
HRESULT result = func(&raw_ptr);
ptr.reset(raw_ptr);
return result;
}
For example, it can be used like this:
std::unique_ptr<IFileDialog, ComDeleter> FileDialog;
/*...*/
using std::bind;
using namespace std::placeholders;
std::unique_ptr<IShellItem, ComDeleter> ShellItem;
HRESULT status = retrieve(bind(&IFileDialog::GetResult, FileDialog, _1), ShellItem);
For bonus points, you can even let retrieve return the unique_ptr instead of taking it by reference. The functor that bind generates should have signature typedefs to derive the pointer type. You can then throw an exception if you get a bad HRESULT.
C++0x smart pointers have a portable way to get at the raw pointer container .get() or release it entirely with .release(). You could also always use &(*ptr) but that is less idiomatic.
If you want to use smart pointers to manage the lifetime of an object, but still need raw pointers to use a library which doesn't support smart pointers (including standard c library) you can use those functions to most conveniently get at the raw pointers.
Remember, you still need to keep the smart pointer around for the duration you want the object to live (so be aware of its lifetime).
Something like:
call_com_function( &my_uniq_ptr.get() ); // will work fine
return &my_localscope_uniq_ptr.get(); // will not
return &my_member_uniq_ptr.get(); // might, if *this will be around for the duration, etc..
Note: this is just a general answer to your question. How to best use COM is a separate issue and sharptooth may very well be correct.
Use a helper function like this.
template< class T >
T*& getPointerRef ( std::unique_ptr<T> & ptr )
{
struct Twin : public std::unique_ptr<T>::_Mybase {};
Twin * twin = (Twin*)( &ptr );
return twin->_Myptr;
}
check the implementation
int wmain ( int argc, wchar_t argv[] )
{
std::unique_ptr<char> charPtr ( new char[25] );
delete getPointerRef(charPtr);
getPointerRef(charPtr) = 0;
return charPtr.get() != 0;
}
I am trying to implement a JSON-RPC solution, using a server connector object which obtains a list of available functions from a server somehow like
NSDictionary *functions = [server
callJSONFunction: #"exposedFunctions" arguments: nil];
which is a simplified description, since callJSONFunction actually triggers an asynchronous NSURLConnection.
An element of the function list consists of a string describing the objective c selector, the original function name which will be called using the mechanism mentioned above, the function signature and an optional array of argument names.
So for example a function list could look like this:
(
#"someFunctionWithArgumentOne:argumentTwo:" =
{
signature = #"##:##",
functionName = #"someFunction",
arguments = ( #"arg_one", #"arg_two" )
},
#"anotherFunction" =
{
signature = #"##:",
functionName = #"anotherFunction"
}
)
As soon as the function list was successfully retrieved, the selectors are added to the server connector instance using class_addMethod in a loop:
for ( NSString *selectorName in functions ) {
SEL aSelector = NSSelectorFromString ( selName );
IMP methodIMP = class_getMethodImplementation (
[ self class ], #selector ( callerMethod: ) );
class_addMethod ( [ self class ], aSelector, methodIMP, "v#:####" );
}
where callerMethod: is a wrapper function used to compose the actual request, consisting of the function name as a NSString and an NSDictionary of the form
{ #"argument1_name" = arg1, #"argument2_name" = arg2, ... }
hence the signature "v#:##". The callerMethod then invokes callJSONFunction on the server.
After this exhausting introduction (my bad, I just did not know, how to shorten it) I'll finally get to the point: to cover the possibility of different numbers of arguments,
I defined the callerMethod like
- (void) callerMethod: (id)argument, ... { }
wherein I use the va_* macros from stdarg.h to obtain the passed arguments. But when I test the mechanism by invoking
[serverConnector someFunctionWithArgumentOne: #"Argument 1"
argumentTwo: #"Argument 2" ];
the first argument returned by id arg = va_arg ( list, id); is always #"Argument 2"!
I'd really appreciate all theories and explanations on why that happens. This thing is really driving me nuts!
Var-args do not map to regular argument passing quite so neatly. Encoding of arguments is actually quite architecture specific and rife with highly entertaining details that sometime seem like they are self-conflicting (until you discover the note about the one exception to the rule that makes the whole thing coherent). If you really want a good read [sarcasm intended], go have a look at how ppc64 handles long doubles sometime; there are cases where half of the double will be in a register and the other half on the stack. Whee!
The above long, and slightly frothy due to scarring, paragraph is to say that you can't transparently forward a call from one function to another where the two functions take different arguments. Since an Objective-C method is really just a function, the same holds true for methods.
Instead, use NSInvocation as it is designed to hide all of the esoteric details of argument encoding that comprises any given platforms ABI.
In your case, though, you might be able to get away with class_addMethod() by defining a set of functions that define all possible combinations of argumentation. You don't even really need to make a dictionary as you can use the dlsym() function to look up the correct function. I.e.
id trampolineForIdIdSELIdIdInt(id self, SEL _cmd, id obj1, id obj2, int) {
... your magic here ...
}
Then, you could translate the type string "##:##i" into that function name and pass it to dlsym, grab the result and use class_addMethod()....
I do feel an obligation to also mention this book as it is a sort of "whoah... man... if we represent classes as objects called meta classes that are themselves represented as classes then we can, like, redefine the universe as metaclasses and classes" ultimate end of this line of thinking.
Also see this unfinished book by Gregor Kiczales and Andreas Paepcke.