passing 2 parameters of undefined type to a constructor (of 2 expected) - function

I have a constructor where as first 2 parameteres I would like to pass:
ID3D11ShaderResourceView* as a steady downloaded texture OR
const CHAR* as a filename to downlowd this texture and assign it to a class ID3D11ShaderResourceView* member (with following release on demand), but I can not understand the way I should do it correctly. it looks this way:
class {button
public
button() {};
button(data1 (or texture or filname), data2 (or texture or filname), rest data....);
...
~button();
}
so I tried:
templates but failed, may be cause of knowledge lack, templates
define one type while I need a choice of 2. Varradic templates, or I didnt get them right but they mean undetermined amount of variables when I need to differ only 2 first.
Unions but it had conflict with class variable set - said could not match const char [amount] with const char* and unions do not work with std::string.
tried void* with typeid.name() but it always showed me "void *"
I don't want to overload constructors, becuase this will create 4+ of them barely differing one from another. Do you think boost::variant helps me in this case? Is there any smooth and effective way to build that kind of constructor? My c++ knowledge is on beginning level, sorry if its a duplicate topic, read all it suggested to me while creating it but didn't seem to find out anything closely similar, thanks:)
Update:
Applied boost::any, got next results:
class button : public frame {
public:
button() {};
button(boost::any _texture,
boost::any _hover_texture,
...
};
if (_texture.type() == typeid(ID3D11ShaderResourceView*)) texture = boost::any_cast<ID3D11ShaderResourceView*>(_texture);
if (_texture.type() == typeid(const char*))
{
if ( FAILED(D3DX11CreateShaderResourceViewFromFile(gvDevice,boost::any_cast<const char*>(_texture), NULL, NULL, &texture, NULL )) )
mboxout( "loading texture failed.", "UI texture load error", true );
};
if (_hover_texture.type() == typeid(ID3D11ShaderResourceView*)) hover_texture = boost::any_cast<ID3D11ShaderResourceView*>(_hover_texture);
if (_hover_texture.type() == typeid(const char*))
{
if ( FAILED(D3DX11CreateShaderResourceViewFromFile(gvDevice, boost::any_cast<const char*>(_hover_texture), NULL, NULL, &hover_texture, NULL )) )
mboxout( "loading texture failed.", "UI texture load error", true );
};
Is it the only possible decision because this one seems akward for me? Thanks :)

As always, when you have combinatoric explosion/tedious repetition, refactor your code into reusable units.
In this case, your constructor could be just
template <typename T1, typename T2>
button(T1 const& texture, T2 const& hover_texture)
: _texture(load(texture)),
_hover_texture(load(hover_texture))
{
};
And all the loading logic would be inside... you guess it the load function. A sample implementation of that:
static ID3D11ShaderResourceView* load(ID3D11ShaderResourceView* v){
return v; // just return the resources passed in
}
static ID3D11ShaderResourceView* load(char const* fname) {
ID3D11ShaderResourceView* p = NULL;
if (FAILED(D3DX11CreateShaderResourceViewFromFile(gvDevice, fname, NULL, NULL, &p, NULL)))
throw std::runtime_error(std::string("loading texture failed (") + fname + ")");
return p;
}
Note: while we were at it we separated UI from business logic. You do not want to display messageboxes from inside constructors. Ever. You just want to notify the caller of the problem and the caller decides what to do (use another resource, try a different path, retry a download, write a warning message to the log, shut down etc.)
Full Demo
Live On Coliru
#include <iostream>
#include <stdexcept>
///////////////////////////////////////////////////////
// mocking ID3D*
struct ID3D11ShaderResourceView;
enum ERROR_CODE { ERR_OK };
#define FAILED(e) (ERR_OK != (e))
static int gvDevice = 42;
ERROR_CODE D3DX11CreateShaderResourceViewFromFile(int, char const* fname, void*, void*, ID3D11ShaderResourceView**, void*) {
std::cout << "Loaded from " << fname << "\n";
return ERR_OK;
}
//
///////////////////////////////////////////////////////
struct frame{ virtual ~frame() = default; };
class button : public frame {
public:
button() {};
template <typename T1, typename T2>
button(T1 const& texture, T2 const& hover_texture)
: _texture(load(texture)),
_hover_texture(load(hover_texture))
{
};
private:
// TODO Rule-Of-Three constructor/destructorl
// SUGGEST: Rule-Of-Zero using shared pointers instead
ID3D11ShaderResourceView* _texture;
ID3D11ShaderResourceView* _hover_texture;
static ID3D11ShaderResourceView* load(ID3D11ShaderResourceView* v) { return v; }
static ID3D11ShaderResourceView* load(char const* fname) {
ID3D11ShaderResourceView* p = NULL;
if (FAILED(D3DX11CreateShaderResourceViewFromFile(gvDevice, fname, NULL, NULL, &p, NULL)))
throw std::runtime_error(std::string("loading texture failed (") + fname + ")");
return p;
}
};
#include <cassert>
int main() {
ID3D11ShaderResourceView* default_texture = NULL;
assert(!FAILED( D3DX11CreateShaderResourceViewFromFile(gvDevice, "default_texture.bin", NULL, NULL, &default_texture, NULL)));
try {
button button1("t1.bin", "hover1.bin");
button button2(default_texture, "hover2.bin");
button button3("t3.bin", default_texture);
button button4(default_texture, default_texture);
} catch(std::exception const& e) {
std::cout << "Oops: " << e.what() << "\n";
}
}
Prints:
Loaded from default_texture.bin
Loaded from t1.bin
Loaded from hover1.bin
Loaded from hover2.bin
Loaded from t3.bin
There's still a lot to be improved (see the comments, e.g.) but this is a start.

Related

Mongoose C++: How to parse HTTP GET or POST request using mongoose?

I am trying to create a simple c++ web-based GUI. I am not interested in using Qt or Visual Studio based GUI. I am rather interested in web based as my requirements are very minimal and basic.
So I came across "Mongoose" the C-based web server. After going through the examples I cooked up some code but it's not working as I have almost zero knowledge about internet programming. I was wondering if any of you have a simple example where I can retrieve the user data from the HTML form either using POST or GET request.
Here is what I have managed so far:
//////
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mongoose.h"
static const char *s_http_port = "8000";
volatile bool kill_server = FALSE;
struct mg_mgr mgr;
struct mg_connection *nc;
bool control1_triggered = FALSE;
bool control2_triggered = FALSE;
struct file_writer_data {
FILE *fp;
size_t bytes_written;
};
static void handle_upload(struct mg_connection *nc, int ev, void *p) {
printf("Signal received! %d\n", ev);
control1_triggered = TRUE;
struct mg_http_multipart_part *mp = (struct mg_http_multipart_part *) p;
printf(mp->data.p);
switch (ev) {
case MG_EV_HTTP_PART_DATA:
break;
}
}
static void handle_upload2(struct mg_connection *nc, int ev, void *p) {
printf("Signal received#2! %d\n", ev);
control2_triggered = TRUE;
}
void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
(void)ev_data;
switch (ev) {
case MG_EV_HTTP_REQUEST:
// Invoked when the full HTTP request is in the buffer (including body).
mg_printf(nc, "%s",
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Connection: close\r\n"
"\r\n"
"<html><body>Controls"
"<form method=\"GET\" action=\"/upload\" "
" enctype=\"multipart/form-data\">"
"<input type = \"text\" name = \"fname\" value = \"John\">"
"<input type=\"submit\" value=\"Fix Position\" />"
"</form>"
"<form method=\"POST\" action=\"/Kill\" "
" enctype=\"multipart/form-data\">"
"<input type=\"submit\" value=\"Kill Server\" />"
"</form>"
"input.search{width: 20em; height: 2em;}"
"</body></html>");
nc->flags |= MG_F_SEND_AND_CLOSE;
break;
}
}
int main() {
mg_mgr_init(&mgr, NULL);
nc = mg_bind(&mgr, s_http_port, ev_handler);
mg_register_http_endpoint(nc, "/upload", handle_upload);
mg_register_http_endpoint(nc, "/Kill", handle_upload2);
// Set up HTTP server parameters
mg_set_protocol_http_websocket(nc);
while (1);
return 0;
}
Please note I have been googling around 3 days now, have seen most of the links and questions. But not a lot of support with Mongoose
Could you please help me with an example on how to parse GET or POST HTML request using Mongoose ?
Thank you so much.
Cheers,
Avi
You access post data from nc->content, to get a certain value you use mg_get_var(nc, size of nc, "fname", buffer, size of buffer).
Example:
int size = 1024, ret;
char *buffer = new char[size];
mg_get_var(nc, sizeof(nc), "fname", buffer, size);
Side note Gregwar made a C++ wrapper for Mongoose, its an older version (by about four years) but it might help, link.
Edit:
Method should be mg_get_http_var not mg_get_var
int size = 1024, ret;
char *buffer = new char[size];
mg_get_http_var(nc, "fname", buffer, size);
Link

C++ Linked List Deep Copy Constructor and Assignment Overloaded

#ifndef LIST
#define LIST
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
typedef string ElementType;
class List
{
private:
class Node
{
public:
ElementType data;
Node * next;
Node()
:data(ElementType()), next(NULL)
{}
Node(ElementType initData)
:data(initData), next(NULL)
{}
}; // end of Node class
typedef Node * NodePointer;
public:
private:
NodePointer first;
int mySize;
}; // end of List class
This is my overloaded assignment operator, im not sure what im doing wrong, but im beyond frustrated,I've searched the web and read different forums and cannot find a solution to do this, could someone please push me in the right direction, I left out all my public member functions, because none of them operate on my overloaded assignment and copy constructor, I just wanted you guys to get an idea of my layout
overloaded assignment operator
List & List::operator=(const List &rightSide)
{
if(this != &rightSide)
{
this->~List();
}
NodePointer ptr = rightSide.first;
NodePointer cptr = ptr;
while(ptr != NULL)
{
cptr->next = new Node(ptr->data);
cptr = cptr->next;
ptr = ptr->next;
}
return *this;
}
this is my copy constructor
List::List(const List &source)
{
NodePointer ptr = source.first;
NodePointer cptr;
if(ptr == NULL)
{
cerr << "Bad allocation, empty list" << endl;
exit(1);
}
while(ptr != NULL)
{
cptr = new Node(ptr->data);
cptr->next = ptr->next;
ptr = ptr->next;
}
}

How to call exported function from dll in C/C++?

My aim is to call some function via its address. How can I do it?
I have done the next work for such aim, but at first(1) - I've got access violation ( don't know why ) and with the second I have some problems with calling function is ASM with ESP value...
The first (the problem with access violation):
#include <iostream>
#include <Windows.h>
const DWORD_PTR offset = 0x00001a90;
typedef void (__stdcall *uef)(int);
int main(void)
{
HMODULE hModule = LoadLibrary(L"C:\\Windows\\system32\\OpenAL32.dll");
DWORD_PTR addr = (DWORD_PTR)hModule + offset;
uef func = (uef)offset;
func(0);
return 0;
}
The second (problems at runtime with ESP value):
#include <iostream>
#include <Windows.h>
typedef void (__stdcall *uef)(int);
int main(void)
{
HMODULE hModule = LoadLibrary(L"C:\\Windows\\system32\\OpenAL32.dll");
uef obj = NULL;
if(hModule != NULL)
{
obj = reinterpret_cast<uef>(GetProcAddress(hModule, "alEnable"));
}
if(obj != NULL)
{
(*obj)(0);
}
if(hModule != NULL)
{
FreeLibrary(hModule);
}
return 0;
}
How could I solve this problem?
PS
And the another main question is:
How can I dynamically calculate the function address in runtime for next calling?
Thanks,
Best Regards!
First, there is a major issue (hence the access violation) with the hardcoded address offset (const DWORD_PTR offset = 0x00001a90). Don't do that! How can you know that the offsett will not be changed because of ASLR?

How to call MessageBox with GetProcAddress function?

I want to call MessageBox() function in such way:
1). load needed library
2). get the function address
3). call it
So, for such aim as I understand, I should define new type with all types of arguments in MessageBox function.
It returnes INT and accepts: HWND, LPCSTR, LPCSTR, UNIT.
So I registred new type:
typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);
I have problems with calling such function. Does such way work for all functions or only for exported?
How can I call MessageBox exactly in such way?
Full code:
#include <iostream>
#include <windows.h>
using namespace std;
typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);
int main(void)
{
HINSTANCE__ *hModule = LoadLibrary(L"\\Windows\\System32\\User32.dll");
msgbox *me = 0;
if(hModule != 0)
{
me = (msgbox*)GetProcAddress(hModule, "MessageBox");
}
return 0;
}
Why are you declaring everything as a pointer?
LoadLibrary returns an HMODULE, not an HINSTANCE__ * (it will work with the latter but it's always better to adhere to the documentation).
Similarly, msgbox is typedef'd to a function pointer type, so me is a msgbox, not a msgbox *.
The reason why GetProcAddress fails is because user32.dll exports 2 functions, MessageBoxA and MessageBoxW. When you simply call MessageBox in your code, macros defined in Windows.h replace it with one of the 2 actual function names depending on whether you're compiling for UNICODE or not. But when you're trying to directly access the exported function as you are doing, you need to explicitly specify which one you're trying to get a pointer to.
#include <iostream>
#include <windows.h>
typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);
int main(void)
{
HMODULE hModule = ::LoadLibrary(L"User32.dll");
msgbox me = NULL;
if( hModule != NULL ) {
me = reinterpret_cast<msgbox>( ::GetProcAddress(hModule, "MessageBoxA") );
}
if( me != NULL ) {
(*me)( NULL, "I'm a MessageBox", "Hello", MB_OK );
}
if( hModule != NULL ) {
::FreeLibrary( hModule );
}
}

Allocate constant memory

I'm trying to set my simulation params in constant memory but without luck (CUDA.NET).
cudaMemcpyToSymbol function returns cudaErrorInvalidSymbol. The first parameter in cudaMemcpyToSymbol is string... Is it symbol name? actualy I don't understand how it could be resolved. Any help appreciated.
//init, load .cubin
float[] arr = new float[1];
arr[0] = 0.0f;
int size = Marshal.SizeOf(arr[0]) * arr.Length;
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(arr, 0, ptr, arr.Length);
var error = CUDARuntime.cudaMemcpyToSymbol("param", ptr, 4, 0, cudaMemcpyKind.cudaMemcpyHostToDevice);
my .cu file contain
__constant__ float param;
Working solution
cuda.LoadModule(Path.Combine(Environment.CurrentDirectory, "name.cubin"));
simParams = cuda.GetModuleGlobal("params");
float[] parameters = new float[N]{...}
cuda.CopyHostToDevice<float>(simParams, parameters);
Unfortunately the __ constant __ must be in the same file scope as the memcpy to the symbol, and in your case your __ constant __ is in a separate .cu file.
The simple way around this is to provide a wrapper function in your .cu file, for example:
__constant__ float param;
// Host function to set the constant
void setParam(float value)
{
cudaMemcpyToSymbol("param", ptr, 4, 0, cudaMemcpyHostToDevice);
}
// etc.
__global__ void ...
If this question is actual you can use cuModuleGetGlobal and next cudaMemcpy like this:
private bool setValueToSymbol(CUmodule module, string symbol, int value)
{
CUdeviceptr devPtr = new CUdeviceptr();
uint lenBytes = 0;
CUResult result = CUDADriver.cuModuleGetGlobal(ref devPtr, ref lenBytes, module, symbol);
if (result == CUResult.Success)
{
int[] src = new int[] { value };
cudaError error = CUDARuntime.cudaMemcpy(devPtr, src, lenBytes, cudaMemcpyKind.cudaMemcpyHostToDevice);
if (error == cudaError.cudaSuccess)
return true;
else
return false;
}
else
{
return false;
}
}
where CUmodule module = cuda.LoadModule("MyCode.cubin");
This code works with NVIDIA GPU Computing SDK 3.1 and CUDA.NET 3.0.
constant memory has implicit local scope linkage.
make sure declaration is in the same file where you use it. it sounds like you have two files.
may also have to declare param to array (or maybe not)