i have a c++ dll (Cli) that is calling to methods in a c# dll.
the c# dll has the following method signature:
Class MyClass
{
void DoSomeWork(ref ClassA a, ClassB b);
}
if there was no ref in the signature my code is something like this:
MyClass^ myClass = gcnew MyClass();
ClassA a = gcnew ClassA();
ClassB b = gcnew ClassB();
myClass->DoSomeWork(a, b);
how do i call it from the c++ code if there is a ref in the signature?
one more queastion i have -
in c# i can call the Any() method on array but for some reason doing it the c++/cli is not working
if (reply->Any())
i get an error: error C2039: 'Any' : is not a member of 'System::Array'
any help would be appricated
thx
If you compile your C++ DLL as a Managed Assembly then you should be able to access it just like you do with any C# assembly.
1a) You could use: myClass->DoSomeWork(*a, b);
1b) If ClassA is a class then ref is redundant anyway.
2) regarding if (reply->Any()) check whether you have in your source code: using namespace System::Linq;
You do not need to do anything to pass ref parameters in C++/CLI. The method void DoSomeWork(ref ClassA a, ClassB b); in C# is seen as void DoSomeWork(ClassA^% a, ClassB^ b); in C++/CLI. Think of the % as equivalent to & in unmanaged C++: you don't need to add anything special to the method call to pass the parameter that way.
Any() is an extension method, defined on Linq::Enumerable. See this answer for how to call extension methods in C++/CLI.
Related
I have a situation. I would appreciated if anyone has a solution for this
I have an objC enum say Abc
I declare this in a swift class, say, MySwiftClass.swift as var abc : Abc!
I have created an instance of MySwiftClass (mySwiftClass) in another ObjC class (myObjC.m file)
In myObjC.m, I’m trying to access enum Abc as mySwiftClass.abc.
This is throwing an error - “Property ‘abc’ not found on object of type MySwiftClass *”.
Basically the enum is not added as property in the “ProjectName-Swift.h” file.
What I believe is happening is that when I’m declaring the ObjC enum in Swift class, it is getting converted to a swift enum and hence I’m not able to access it in ObjC file.
Note: Marking the Swift class as #objc did not work.
Numeric Swift optionals cannot be represented in Objective-C, and thus will not be exposed to Objective-C. Declare abc to not be optional and it should be available from Objective-C.
Consider this Objective-C enumeration:
typedef NS_ENUM(NSInteger, Foo) {
FooBar,
FooBaz,
FooQux
};
Then consider this Swift 3 class:
class SomeObject: NSObject {
var foo1: Foo = .bar // this is exposed to Objective-C
var foo2: Foo! = .bar // this is not
}
The non-optional, foo1, will be exposed to Objective-C, whereas the optional, foo2, will not.
I am a calling c++ method from objective c:
C++ Method:
void TestMethod( size_t& outputSize,
OutputArray& outputArray );
Objective C:
-(void) testMethodObjc : outputSize,
OutputArrayObjc : outputArray
{
TestMethod( outputSize, [outputArray getArray ]);
}
How do I accomplish this? I hear from other postings that objective-c does not support pass by reference.
You should be able to - Obj-C is a strict subset of C. Just make sure that the file the code is in is a .mm file - not just .m
Objective-C, like C, does not support pass by reference.
Like C, you can take the address of the variable and pass a pointer instead. And to manipulated the original variable in the function you would need to dereference the pointer.
How can you use a Objective C method as an argument for glutDisplayFunc (and functions like it)? I'm quite new to ObjC, so I don't completely know how this works
In C++, you can just pass in a void, but in ObjC, I tried this:
//...
glutDisplayFunc([self display]);
//...
-(void) display{
glutPostRedisplay();
}
I've also tried static methods
//...
glutDisplayFunc([self display]);
//...
+(void) display{
glutPostRedisplay();
}
but every time I get the error "passing 'void' to parameter with incompatible type void(*)(void)".
I thought you could just pass in a void.
So, how can I make this work (it has to be a method)
In C++, you can just pass in a void
No, you can't.
So, how can I make this work (it has to be a method)
You can't. What you're interested in would be as something known as closure or delegate, but GLUT will just take global scope C style callback functions. The best thing you could to was write a global scope wrapper with a calling convention compatible to C, which then calls the method of a global scope class instance.
I tried making an extension to the built-in String class using C++/CLI, and using it from C++/CLI without success.
Here's the simplest I can boil it down to:
[System::Runtime::CompilerServices::Extension]
public ref class MyStringExtensions abstract sealed {
public:
[System::Runtime::CompilerServices::Extension]
static bool TestMethod(System::String^ str) { return false; }
};
Now, when I try to use this in other C++/CLI code, I get a compiler message indicating that TestMethod is not a method of String.
String^ foo = gcnew ...
...
blah = foo->TestMethod(); // compile-error
Any ideas?
C++ doesn't have extension methods.
But it does have ADL (Argument-dependent lookup, also known as Koenig lookup) which is arguably even nicer.
i have helper C functions in some Objective C classes.
Just found out that the values of global, static C variables which i use in these functions are shared between instances of the class (duh), which is not what i want.
Is there a way to declare these variables local to instances of the class, so that they are visible by the helper functions without passing them explicitly?
Is there a way to declare these variables local to instances of the class
Sure, make them instance variables.
But:
so that they are visible by the helper functions without passing them explicitly?
You can pass the object into the function. If you have appropriate accessors, the function can get them. And if you have mutators, it can modify them, too.
But if you're doing that, you might as well just create a method, and automatically have access to the instance variables.
want to avoid method calls where necessary
logically separate it so your low level code is in c or c++, then add the required data to your objc class:
/* c example */
typedef struct t_generator {
UInt32 a;
} t_generator;
static void Generate(t_generator* const gen) {
/.../
}
#interface MONObjCGeneratorContainer : NSObject
{
t_generator generator;
NSString * name;
UInt32 b;
}
#end
if the data interface is as simple you can just access them from the instance:
- (void)method { GenerateB(&b); }
that should meet all the requirements you have posted (so far).