I'am coding with objective-c. I found that the parameter and return value of 'objc_msgSend' are all void types. But I can cast it to an appropriate function pointer type before call it. My question is how can I implement a function with void type parameter and return value, and call it like 'objc_msgSend' ? Thanks!
// declaration
OBJC_EXPORT void objc_msgSend(void /* id self, SEL op, ... */ )
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
// how I used it.
((void(*)(id, SEL))(void *)objc_msgSend)(self, #selector(originalMethod));
Related
For example I'm having a class with three overloaded methods like this:
class MyClass
{
int sum(int i)
{
// Method implementation.
}
int sum(string x)
{
// Method implementation.
}
int sum(object o)
{
// Method implementation.
}
}
My question is when I call the sum method of MyClass by passing any value (integer, string or object) it should invoke only third method (with object type input parameter)
class MainClass
{
static void Main(string[] args)
{
MyClass obj = new MyClass();
obj.sum(10);
obj.sum("X")
}
}
You said "without type casting" but you can't, because you need some way to indicate to the compiler which version to call, and the runtime uses the type it sees to do that bit. Boxing the int as an object means the compiler will pick the object version
sum(1);//call int version
sum((object)1); //call object version
sum((string)(object)"1"); //call string version
sum((object)(int)(object)1); //call object version
First of all, let me say that if you sometimes want to call one version of the sum function when working with ints and sometimes want to call another, overloading probably isn't the right tool to use. Overloading works best when you are implementing conceptually the same operation for a number of different types, and you want the compiler to figure out automatically which function is the right one to call for each type; if you need more manual control over which function is called, you're probably better off using different names.
That said, if you're sure that this is what you want to do, you could implement the overloaded version for object in terms of another function in the public interface, as in:
class MyClass
{
int sum(int i)
{
// Method implementation.
}
int sum(string x)
{
// Method implementation.
}
int sum(object o)
{
sum_object(o);
}
int sum_object(object o)
{
// Method implementation for objects
}
}
Then, when you want to apply the object version to int and string objects, you just call sum_object directly instead.
Is there any way to pass a function pointer to an Objective C method, and then have that method modify the function pointer to point at a C function somewhere else?
Creating a method that accepts a function pointer is simple enough:
- (void)doSomethingWithFunctionPointer:(void(*)(/* args go here */))functionPointer;
I can then call that function inside doSomethingWithFunctionPointer simply by calling:
if (functionPointer)
{
functionPointer();
}
But what if I actually wanted to change the functionPointer to point at something else within doSomethingWithFunctionPointer, so that any code outside that method can then call the changed function pointer to call the function that doSomethingWithFunctionPointer point it to?
I know this is probably a prime example of how not to do things in Objective C (especially considering we've got blocks and what not). It's more just curiosity at this point. It almost sounds like I'd need a function pointer pointer, but I'm not sure how that would work, if it's even possible.
This can be done using pointers to function pointers. Perhaps the most readable way to do it is to typedef your function pointer, like this:
typedef void (*FunPtr)(int a, float b);
Then use a pointer of that typedef-ed type to assign in a function, like this:
void foo(int a, float b) {
printf("FOO : %d %f\n", a, b);
}
void bar(int a, float b) {
printf("BAR : %d %f\n", a, b);
}
// This function receives a pointer to function pointer
void assign(int n, FunPtr *ptr) {
if (n == 0) {
*ptr = foo;
} else {
*ptr = bar;
}
}
Here is how you call assign from your code:
int main(void) {
FunPtr f;
assign(0, &f);
f(10, 20.5);
assign(1, &f);
f(10, 20.5);
return 0;
}
Demo.
Note: You are right about blocks in Objective-C greatly reducing the need for direct use of function pointers. However, you can use a similar typedef trick with pointers to blocks.
This question already has answers here:
What Does "Overloaded"/"Overload"/"Overloading" Mean?
(8 answers)
Closed 9 years ago.
I've found resources that say method overloading is the ability for a language to use the same method with a different outcome, depending on context.
Somehow, when I read other definitions, I fell like that's not the whole definition. Is there more to method overloading?
That's just a very general way of describing it. Method overloading allows you to use a single method name, but "overload it" (provide more than one version) depending on "context" (which is typically the type or number of arguments passed in). Since each method is separate, they can cause a "different outcome".
For example, using C#, you can write:
void Foo() // Version with no arguments
{
}
void Foo(int arg) // Version with a single int
{
}
void Foo(string arg1, double arg2) // Version with string and double parameters
{
}
First, you should know what is signature in programming. A signature of a function is its representation; the name of a function and its parameters determine its signature.
Overloading means changing the signature of a function to meet our needs.
Have a look at the following example:
int sum(int x, int y, int z) {
return x + y + z;
}
int sum(int x, int y) {
return x + y;
}
Now, the function sum() can be called through two different ways: Either you can call it with two arguments or you can call it with three arguments. you have changed its signature to meet your needs. Instead of writing a separate function for two arguments, you put the load on the same function, that is why this is known as overloading.
It's where you have a multitude of methods of the same name with different parameters.
public void kittens(String paws) {
}
public void kittens(String paws, boolean tail) {
}
Both can be called independently to one another with either
kittens("fat");
or
kittens("thin", true);
The context in this case is determined by the argument signature of the method, i.e. the number and type of the arguments.
For example:
methodName(int x, int y, int w, int h)
methodName(Vector x)
The first method implementation would be an alternative to:
methodName(new Vector(x, y, w, h))
Is the ability of some languages to create methods/function with the same name but that differ for input / otput parameters.
A classical example is the class constructor overloading example in Java:
//Constructor without parameters
public User() {
}
//Constructor with only one parameter
public User(String username)
{
this.username = username;
}
//Constructor with two parameters
public User(String username, int age)
{
this.username=username;
this.age=age;
}
You have a class with different constructors that accept different parameters, as you see they differ in their signature.
I've got an Interop wrapper to some unmanaged DLL calls that return details through out paremeters. The functions appear like this:
_myWrapper->My_Method( ... out UInt32 value ... );
So assuming the method is declared like this:
void My_Method(out UInt32 value);
How do I then call this method from within my C++/CLI code? I know how to call reference methods such as this easy enough:
void Another_Method(ref UInt32 value);
UInt32 _value;
_myWrapper->Another_Method(%_value);
I'm doing a little reading and I am reading it can't be done? I don't believe it... Likely this isn't impossible to overcome or workaround, but you've got to be kidding me? Is that really true?
Thank you...
In C++, there's no special call syntax for calling a function with a reference parameter, you just write the call like it was pass-by-value. Of course, you need to supply an lvalue to be overwritten, the rvalue (temporary) result of an arithmetic expression can't be used.
BTW, your code for calling a ref function is wrong too, that might be the source of your troubles.
Example:
C# definition:
void MySharpRef(ref int i) { i = 4; }
void MySharpOut(out int i) { i = 5; }
C++/CLI definition:
void MyPlusRef(System::Int32% i) { i = 14; }
void MyPlusOut([System::Runtime::InteropServices::OutAttribute] System::Int32% i) { i = 15; }
C# call:
int j;
o.MyPlusOut(out j);
o.MyPlusRef(ref j);
C++/CLI call:
System::Int32 k;
p->MySharpOut(k);
p->MySharpRef(k);
I want to search an array of NSDate, so here what I do:
searchResult = CFArrayBSearchValues((CFArrayRef)someDateArray, arrayRange, dateToFind, CFDateCompare, nil);
However, I get this warning:
Incompatible pointer types passing 'CFComparisonResult (CFDateRef, CFDateRef, void )' to parameter of type 'CFComparatorFunction' (aka 'CFComparisonResult ()(const void *, const void *, void *)')
How do I properly pass a function as a parameter? I think I got my syntax wrong.
You need to cast the function pointer to the CFComparatorFunction type, since it has a more explicit signature (it uses CFDateRef instead of void *).
searchResult = CFArrayBSearchValues((CFArrayRef)someDateArray, arrayRange, dateToFind, (CFComparatorFunction)CFDateCompare, nil);