I am new to c++/cli, the situation I faced is that:
the project I am doing needs to use an external dll, in my functions I need to use classes A, B and C which are from this dll, I put them in my .h file, the .h file looking like:
#include library I use
public ref class MyClass
{
public:
MyClass();
~MyClass();
otherfuc();
private:
A *a;
B *b;
C *c;
}
My .cpp file looking like:
MyClass::MyClass()
{
a = new A();
b = new B(*a);
c = b->func(); //error happened
}
MyClass::otherfunc()
{
c->func_c()
}
Class A, B, C are unmanaged class, so I only have one way to declare them in managed class, just like I do in the header file. In class B, it has a function which is called func, this function return class type C, I tried c = &b->func(), in this way, it will throw AccessViolationException, if I tried c = b->func, then the error is function call missing argument. What should I do, please help!!!
From what you've written my guess is that B::func() is declared to return a C instance as a temporary:
class B {
public:
C func();
};
Allocate an instance of C as a copy of temporary:
class A {
};
class C {
public:
C(int _i) : i(_i) {}
int func_c() { return i; }
int i;
};
class B {
public:
B(A & a) {}
C func() { return C(5); }
};
public ref class MyClass {
public:
MyClass();
~MyClass();
int otherfunc();
private:
A *a;
B *b;
C *c;
};
MyClass::MyClass()
{
a = new A();
b = new B(*a);
c = new C(b->func());
}
MyClass::~MyClass() {
delete a;
delete b;
delete c;
}
int MyClass::otherfunc()
{
return c->func_c();
}
void f() {
MyClass^ mc = gcnew MyClass();
int i = mc->otherfunc();
}
This assumes C is copyable (or moveable) and that copying it make sense for what you are doing.
Related
class abc
{
};
int main()
{
std::map<abc, int> m;
abc ob, ob1;
m.insert(std::make_pair(ob, 1));
m.insert(std::make_pair(ob1, 2));
}
Error coming is:
/usr/lib/gcc/i686-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_function.h:237:22: note: ‘const abc’ is not derived from ‘const std::multimap<_Key, _Tp, _Compare, _Alloc>’
Does any addition function need be added in class so that it can be made hashable?
Got it. Since std::map sorts when entering a new key in map, so if key is a class object, we must overload class's "<" operator, then it would work fine.
class abc
{
public:
bool operator< (const abc& userObj) const
{
return true;
}
};
int main()
{
std::map<abc, int> m;
abc ob;
abc ob1;
m.insert(std::make_pair(ob, 1));
m.insert(std::make_pair(ob1, 2));
}
I am trying to access a managed function from native code.
I created a c++/cli dll in visual studio 2010 with CLR option.
This is my c# code:
namespace ManagedNamespace
{
public class Managed
{
public void CSharpFunc()
{
.
.
.
}
}
}
This is my c++\CLI code (the project refer to the c# project - and I compile this code to Wrapper.dll):
#ifdef __cplusplus
extern "C"
{
#endif
__declspec(dllexport) void CLIFunc(const std::string& a, const std::string& b, std::string& c)
{
System::String^ new_a = gcnew System::String(a.c_str()); //OK
System::String^ new_b = gcnew System::String(b.c_str()); //OK
Text::StringBuilder^ new_c = gcnew Text::StringBuilder(""); //OK
ManagedNamespace::Managed^ m = gcnew ManagedNamespace::Managed(); //this line is the problematic line
m->CSharpFunc();
}
I call this function from another dll and get EXCEPTION_EXECUTE_HANDLER when I create ManagedNamespace::Managed object. This is the code:
typedef void (WINAPI *CLIFuncPtr)(const std::string& a, const std::string& b, std::string& c);
.
.
.
HMODULE mod = LoadLibraryA("c:\\mydir\\Wrapper.dll");
if (mod!= NULL)
{
CLIFuncPtr FuncPtr = (CLIFuncPtr)GetProcAddress(mod, "CLIFunc");
if (FuncPtr != NULL)
{
FuncPtr (aa, bb, cc);
}
}
Appreciate any help,
Thanks
I think that LoadLibrary works only with unmanaged code
What does one do to make something like this work?
void (^)(void) *someBlock = ^{
//some code
};
Dmitry's answer is exactly right. Think of the block syntax as a C function declaration:
// C function -> <return type> <function name> (<arguments>)
void someFunction(void)
{
// do something
}
// block -> <return type> (^<block variable name>) (<arguments>)
void (^someBlock)(void) = ^{
// do something
};
Another example:
// C function
int sum (int a, int b)
{
return a + b;
}
// block
int (^sum)(int, int) = ^(int a, int b) {
return a + b;
};
So just think of the block syntax as a C function declaration:
First the return type int, then the name of the block variable (^sum) and then the list of arguments types (int, int).
If, however, you need a certain type of block frequently in your app, use a typedef:
typedef int (^MySumBlock)(int, int);
Now you can create variables of the MySumBlock type:
MySumBlock debugSumBlock = ^(int a, int b) {
NSLog(#"Adding %i and %i", a, b);
return a + b;
};
MySumBlock normalSumBlock = ^(int a, int b) {
return a + b;
};
Hope that helps :)
Just block syntax
void (^someBlock)(void) = ^{
//some code
};
Suppose I have two classes:
class1 {
int m_i;
std::string m_s;
};
class2 {
int m_i2;
class1 *m_ptr;
};
Now, I want to send a class2 variable over network, and want to use any of the libraries that does serialization.(Protocol-buffers, Thrift, MessagePack..)
Which one can I use?(note the class1* m_ptr)
You could use thrift for this.
the definition would look something like
struct class1 {
1: required i32 m_i;
2: required string m_s;
}
struct class2 {
1: required i32 m_i2;
2: optional class1 m_ptr;
}
You would like to read this excellent guide
http://diwakergupta.github.com/thrift-missing-guide/
and to get clarity on concern about the "pointer" issue that you mentioned in the question,read the section on "How are nested structs initialized?" in the above guide.
Using google protocol buffers, you would need a .proto file (say test.proto) like:
package serialisation; // puts this in namespace serialisation
message class1 {
required int32 m_i = 1;
required bytes m_s = 2;
}
message class2 {
required int32 m_i2 = 1;
optional class1 m_ptr = 2;
}
Using C++, once you run the protoc compiler against this, you end up with test.pb.cc and test.pb.h
You can then use these like:
#include <string>
#include "test.pb.h"
struct class1 {
int m_i;
std::string m_s;
};
struct class2 {
int m_i2;
class1 *m_ptr;
};
int main() {
class2 second_class;
second_class.m_i2 = 2;
second_class.m_ptr = new class1;
second_class.m_ptr->m_i = 1;
second_class.m_ptr->m_s = "one";
// Serialise class 2
serialisation::class2 serialisable_second_class;
serialisable_second_class.set_m_i2(second_class.m_i2);
if (second_class.m_ptr) {
serialisation::class1* serialisable_first_class = serialisable_second_class.mutable_m_ptr();
serialisable_first_class->set_m_i(second_class.m_ptr->m_i);
serialisable_first_class->set_m_s(second_class.m_ptr->m_s);
}
std::string serialised(serialisable_second_class.SerializeAsString());
// Parse class 2
serialisation::class2 parsed_second_class;
parsed_second_class.ParseFromString(serialised);
class2 retrieved_second_class;
retrieved_second_class.m_i2 = parsed_second_class.m_i2();
if (parsed_second_class.has_m_ptr()) {
retrieved_second_class.m_ptr = new class1;
retrieved_second_class.m_ptr->m_i = parsed_second_class.m_ptr().m_i();
retrieved_second_class.m_ptr->m_s = parsed_second_class.m_ptr().m_s();
} else {
retrieved_second_class.m_ptr = nullptr;
}
return 0;
}
Note, for the sake of brevity I'm not doing any error checking or exception handling here - this would be needed in production code. I'm also not managing the lifetime of the class1 pointer.
How do i test that an object is an instance of a particular class in D?
Something akin to Javascript's instanceof keyword?
Use cast. It returns a null reference when you attempt to cast to a subclass it isn't an instance of (like C++'s dynamic_cast).
auto a = new Base;
auto b = cast(Child) a;
assert(b is null);
a = new Child;
auto c = cast(Child) a;
assert(c !is null);
typeid expression can tell you if instance is of some exact type (without considering inheritance hierarchy):
class A {}
class B : A {}
void main()
{
A a = new B();
// dynamic
assert( typeid(a) == typeid(B) );
// static
assert( typeid(typeof(a)) == typeid(A) );
}