I have been trying to do the following to no avail,
In 'used.h',
#ifndef USED_H_
#define USED_H_
#include<iostream>
#include<string>
class used
{
public:
int member=0;
used();
virtual ~used();
};
#endif
In the used.cc,
#include "used.h"
used::used()
{
}
used::~used()
{
}
In 'the_user.h',
#ifndef THE_USER_H_
#define THE_USER_H_
#include<queue>
#include<iostream>
class used; //Class forward declaring
class the_user
{
public:
std::deque<used*> my_queue;
the_user();
~the_user();
};
#endif
Now, I want to access and change 'member' in 'the_user.cc',
#include "used.h"
#include "the_used.h"
#include<iostream>
#include<queue>
using namespace std;
the_user::the_user()
{
deque <used*> my_queue;
my_queue.resize(6);
used* object = new used; <-------marked line
for(unsigned int i=0; i<my_queue.size(); i++)
{
my_queue.push_back(object);
}
cout << my_queue[5] << endl; //Should give 0
my_queue[0]->member=1000;
cout << my_queue[0]->member << endl; //1000
}
in main file(I have only read access),
#include "the_used.h"
#include <iostream>
#include <stdlib.h>
#include <sstream>
using namespace std;
int main()
{
the_used *object = new the_used();
}
Actually, I am getting undefined reference to used::used() at the marked line. What seems to be the problem?
I have tried to use the same for a vector as well but to no avail.
I am not allowed to make changes to the 'int main(){}'.
Any help would be highly appreciated.
Your class declaration doesn't declare any constructor or destructor:
class used
{
public:
int member=0;
};
But in your cpp file you define them. Your compiler should complain already here:
#include "used.h"
used::used()
{
}
used::~used()
{
}
You must declare constructor and destructor in your class:
class used
{
public:
used();
~used();
int member=0;
};
Then here:
my_queue.resize(6);
you will actually create 6 pointers that will be initialized to nullptr. Maybe you're aware of that, since you expect my_queue[5] to return 0.
Then in your loop, everytime you do this:
my_queue.push_back(object);
you will increase the size of my_queue by one, thus make your loop run forever.
Apart from that: Do. Not. Do. using namespace std;. Ever.
Related
Im trying to write a wrapper in c++/cli for an DLL, which code i dont have, only DLL file and header but i created lib file through VS command prompt. When i`m trying to build solution i receive this errors:
DotNetWrappOfAsterSdkDll.obj : error LNK2028: unresolved token (0A00002E) "void __stdcall MuteClearLastError(void)" (?MuteClearLastError##$$FYGXXZ) referenced in function "public: void __clrcall DotNetWrappOfAsterSdkDll::WrapperClass2::doMuteClearLastError(void)" (?doMuteClearLastError#WrapperClass2#DotNetWrappOfAsterSdkDll##$$FQ$AAMXXZ)
DotNetWrappOfAsterSdkDll.obj : error LNK2019: unresolved external symbol "void __stdcall MuteClearLastError(void)" (?MuteClearLastError##$$FYGXXZ) referenced in function "public: void __clrcall DotNetWrappOfAsterSdkDll::WrapperClass2::doMuteClearLastError(void)" (?doMuteClearLastError#WrapperClass2#DotNetWrappOfAsterSdkDll##$$FQ$AAMXXZ)
I tried to create my own DLL and include it to the wrapper, and its working perfectly
here dll created by me which i can use in c++/cli wrapper:
//header file
#pragma once
#define DLLEXP __declspec( dllexport )
namespace Computations {
DLLEXP void someMethod(int number);
}
//cpp file
#include "Computations.h"
#include <iostream>
#include <time.h>
//#include "pnl/pnl_random.h"
using namespace std;
void Computations::someMethod(int number)
{
std::cout << "something "<<number*number << endl;
}
and here is part of header of DLL which i want to use:
#ifndef MUTEIFC_H
#define MUTEIFC_H
#include <Windows.h>
#ifdef MUTEIFC_LIBRARY
# define MUTEAPI extern "C"__declspec(dllexport)
#else
# define MUTEAPI __declspec(dllimport)
#endif
#define MUTECALL __stdcall
/** \ingroup init */
/** Initialization of the ASTER SDK library
* \returns TRUE - success, FALSE - failure (use \ref MuteLastErrorCode or/and \ref MuteLastErrorInfo to get
* failure cause)
* \note This function will require Administrative privileges on the first call on a given computer.
*/
MUTEAPI BOOL MUTECALL MuteIfcInitialize(VOID);
/** \ingroup init */
/** Finialization of the ASTER SDK library
*/
MUTEAPI VOID MUTECALL MuteIfcFinalize(VOID);
/** \ingroup errors*/
/** Clears the calling thread's last-error code and description.
* The last-error is maintained on a per-thread basis. Multiple threads do not overwrite each other's last-error.
*/
MUTEAPI VOID MUTECALL MuteClearLastError(VOID);
#endif // MUTEIFC_H
and my c++/cli code :
//header file
#pragma once
#include "Computations.h"
#include "muteifc.h"
using namespace System;
namespace DotNetWrappOfAsterSdkDll
{
public ref class WrapperClass2
{
public:
void doMuteClearLastError();
};
public ref class WrapperClass
{
private:
public:
void getPriceCallEuro(int number);
};
}
//cpp file
#include "DotNetWrappOfAsterSdkDll.h"
using namespace DotNetWrappOfAsterSdkDll;
using namespace Computations;
namespace DotNetWrappOfAsterSdkDll
{
//this dont work
void WrapperClass2::doMuteClearLastError() {
MuteClearLastError();
}
//this works great
void WrapperClass::getPriceCallEuro(int number) {
someMethod(number);
//MuteIfcFinalize();
}
}
Please tell me what i'm doing wrong
You probably didn't add the lib that contains the function reference to the linker options.
Either the lib contains he code it self or it has a reference to the DLL that must be loaded. The linker will bring your code and the DLL (or static lib) code together...
Is it possible to emit a signal on behalf of another QObject? the reason I would like to do this is that it would be very useful when writing mock/test code and simply want to simulate that a certain object emitted a signal.
I tried to use
QMetaObject::invokeMethod(otherObject, "mySignal", Q_ARG(QString, myArg));
because the documentation says:
[...] Invokes the member (a signal or a slot name) on the object obj.[...]
But this does not work for me. The signal is simply not emitted.
You can simply invoke the signal through the class like so:
otherObject.mySignal("Testing!");
Edit
Good point on the thread-safety issue. I got it to work as well with the invokeMethod solution by explicitly setting the connection type. If your objects are in different threads, you'd need to use the QueuedConnection rather than the DirectConnection. Here is my simple test case:
main.cpp
#include <QObject>
#include "Stub.h"
int main()
{
Stub stub;
Stub2 stub2;
QObject::connect(&stub, &Stub::TestSignal, &stub2, &Stub2::TestReceiver);
QMetaObject::invokeMethod(&stub,
"TestSignal",
Qt::DirectConnection,
Q_ARG(QString, "myArg"));
return 0;
}
Stub.h
#ifndef STUB_H
#define STUB_H
#include <QObject>
#include <QDebug>
class Stub : public QObject
{
Q_OBJECT
signals:
void TestSignal(QString s);
};
class Stub2 : public QObject
{
Q_OBJECT
public:
void TestReceiver(QString s) {qDebug() << "Got s:" << s;}
};
#endif // STUB_H
I have following code
ref class A
{
typedef ref struct All
{
std::string x;
}All_t;
};
in my program I am using it in following manner
A::All_t t;
t.X = "H";
This declaration throwing error as
error C4368: cannot define 'x' as a member of managed 'A::All': mixed types are not supported
I understand that I am declaring native varible inside managed code which is not allowed but now I would like to know changes I will need to make to make my structure suitable to managed project.
Thanks.
I'm assuming you originally had std::string x; not std::string *x (since using the pointer to string does not generate that error). You are not allowed to directly embed a native type in a managed type, but you are allowed to indirectly have one (via a pointer) See:
http://msdn.microsoft.com/en-us/library/xhfb39es(v=vs.80).aspx
After I fixed the compiler errors in your sample, it builds without error:
#include "stdafx.h"
#include <string>
using namespace System;
ref class A
{
public:
typedef ref struct All
{
std::string * x;
}All_t;
};
int main(array<System::String ^> ^args)
{
A::All_t t;
t.x = new std::string("H");
return 0;
}
I need to expose some unmanaged data using CLIWrapper.
Let's say I have a vector, but there is no null-characters in the middle of the vector (for sure). What would be the best way to do this type of assigment/marshalling?
And just in case.... How whould the same operation looks like if I do assigning from vector to cli::array?
You can directly use the String class constructor. Like this:
#include "stdafx.h"
#include <vector>
using namespace System;
int main(array<System::String ^> ^args)
{
std::vector<wchar_t> example;
example.push_back('x');
String^ str = gcnew String(&example[0], 0, example.size());
Console::WriteLine(str);
return 0;
}
I made a DLL with a function named "render()" and I want to load it dynamically to my application, but GetProcAddress cannot find it. Here's the DLL .h:
#ifdef D3D_API_EXPORTS
#define D3D_API_API __declspec(dllexport)
#else
#define D3D_API_API __declspec(dllimport)
#endif
D3D_API_API void render();
And here's DLL .cpp:
#include "stdafx.h"
#include "D3D_API.h"
#include <iostream>
D3D_API_API void render()
{
std::cout << "method called." << std::endl;
}
Here's the application that tries to use that function:
#include "stdafx.h"
#include <windows.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
HINSTANCE myDLL = LoadLibrary( L"D3D_API.dll" );
if (myDLL == NULL) {
std::cerr << "Loading of D3D_API.dll failed!" << std::endl;
}
typedef void (WINAPI *render_t)();
render_t render = (render_t)GetProcAddress( myDLL, "render" );
if (render == NULL) {
std::cerr << "render() not found in .dll!" << std::endl;
}
return 0;
}
My goal is to make a 3D engine that supports both D3D and OpenGL through their own .DLLs using a unified API. I looked at the .dll in notepad and there was a string "render".
The function you export is treated as a C++ function (because of *.cpp file extension) and so C++ name mangling is used to decorate the exported function name. If you use the Dependency Walker tool from Microsoft to inspect your created DLL you will see the functions full name.
You can either use that decorated name in your import code or force the compiler to export your function in C style, that is, in its undecorated form that your current import code expects.
You can tell the compiler to do so by adding extern "C" to your functions signature. Something like this:
extern "C" D3D_API_API void render();
Now your import code should work as expexted.
As the comment to the answer says:
using 'extern "C"' will remove any C++ name mangling, but still leaves
C name mangling. In order to export the plain names you should look at
using a .DEF file. See
blogs.msdn.microsoft.com/oldnewthing/20120525-00/?p=7533
You need to add a new file with .DEF extension to your project, with similar to this contents:
LIBRARY "MyRenderLib"
EXPORTS
render
Then in your DLL header you don't use __declspec(dllexport), but only extern "C"
extern "C" void render();