Organization of Initialization code - c++

Good day,
I have been working on memory allocations for portable use.
I have a header file which contains function prototypes and operator overloads for new and delete.
void* mem_align16(size_t size);
void mem_delete16(void* memory);
I then have cpp files for each operating system implementation.
for example sbrk for linux and HeapAlloc for windows.
when working with windows I must use a handle to do memory allocations.
HANDLE heap_handle = HeapCreate(0, 0, 0);
How would I use the handle in an organized clean manner? As the handle would need to be used at startup inside of main. The only way I can think of using the handle is by having it as a static variable inside of the cpp file where the functions are used and then use a function to update the static variable and then have it forward declared inside of main.cpp
//inside of win32_heap.cpp
static HANDLE heaphandle = 0;
void make_heap_handle(void) {
heaphandle = HeapCreate(0, 0, 0);
}
//inside of win32_main.cpp
void make_heap_handle(void);
int main(int argc, char** argv) {
make_heap_handle();
return (0);
}
For some reason this feels like the wrong thing to do in order to get a usable handle for use with my functions.

You don't need to use HeapCreate() in order to use HeapAlloc()/HeapFree(), you could just use GetProcessHeap() instead:
void* mem_align16(size_t size)
{
// adjust size as needed...
void *memory = HeapAlloc(GetProcessHeap(), 0, size);
if (!memory) return nullptr;
// adjust memory as needed ...
return memory;
}
void mem_delete16(void* memory)
{
// adjust memory as needed...
HeapFree(GetProcessHeap(), 0, memory);
}
However, if you do want to create a private heap of your own, you can create a singleton class that is hidden inside your win32_heap.cpp file to create and destroy your private heap. The rest of your code outside of win32_heap.cpp will not be privy to its existence:
class MyHeap
{
public:
HANDLE hHeap;
MyHeap() {
hHeap = HeapCreate(0, 0, 0);
}
~MyHeap() {
HeapDestroy(hHeap);
}
};
static MyHeap gMyHeap;
void* mem_align16(size_t size)
{
// adjust size as needed...
void *memory = HeapAlloc(gMyHeap.hHeap, 0, size);
if (!memory) return 0;
// adjust memory as needed ...
return memory;
}
void mem_delete16(void* memory)
{
// adjust memory as needed...
HeapFree(gMyHeap.hHeap, 0, memory);
}

Related

Returning custom data structure from C++ via NIF

I have a C++ function which I want to export via NIF. It accepts and operates with custom data structures, std::vectors and the like.
I'm confused about what sequence of steps should be to convert Elixir type into C++ and back.
I'm aware about enif_make_resource(), enif_release_resource() and enif_open_resource_type()
Do they have to be used when returning data? Or only when parsing incoming parameters?
Code, partly:
static int nif_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) {
ErlNifResourceType* rt = enif_open_resource_type(env, nullptr, "vector_of_my_struct_s1",
vec1_dtor, ERL_NIF_RT_CREATE, nullptr);
if (rt == nullptr) {
return -1;
}
assert(vec1_res == nullptr);
vec1_res = rt;
return 0;
}
ERL_NIF_INIT(Elixir.MyApp, nif_funcs, nif_load, nullptr, nullptr, nullptr);
And function:
ERL_NIF_TERM do_cpp_calculations_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
// [........for now, parsing incoming arguments is skipped...]
std::vector<MyStructS1> native_res1 = do_cpp_calculations1(....);
ERL_NIF_TERM term;
// how to return 'native_res1' ?
// do I have to I use these functions at all?
// enif_alloc_resource(...) ?
// enif_make_resource(..) ?
// and how?
return term;
}
In the doc and this module from the official repo you have examples on how to do it.
Usually the steps you need are:
Create empty resource
Operate with the resource
Sometimes you do both in the same function.
Create empty resource:
Example from the doc:
ERL_NIF_TERM term;
MyStruct* obj = enif_alloc_resource(my_resource_type, sizeof(MyStruct));
/* initialize struct ... */
term = enif_make_resource(env, obj);
if (keep_a_reference_of_our_own) {
/* store 'obj' in static variable, private data or other resource object */
}
else {
enif_release_resource(obj);
/* resource now only owned by "Erlang" */
}
return term;
I'd recommend releasing the resource immediately and relying on the GC for the destructor, which should free the vector memory (you should make std::vector use enif_alloc to manage the memory), so in the end you may have something along the lines of:
static ERL_NIF_TERM create(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
void* pointer_to_resource_memory = enif_alloc_resource(vec1_res, sizeof(ResourceStruct));
// TODO Initialize the resource memory
ERL_NIF_TERM ret = enif_make_resource(env, pointer_to_resource_memory);
enif_release_resource(pointer_to_resource_memory);
return ret;
}
Operate with the resource
In order to work with it, you only need to extract the pointer from the resource:
static ERL_NIF_TERM do_stuff(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
void* pointer_to_resource_memory = NULL;
if (!enif_get_resource(env, argv[0], vec1_res, &pointer_to_resource_memory) {
return enif_make_badarg(env);
}
// TODO do stuff with the resource memory
// TODO make a term and return it, no need to create a new resource
return enif_make_int(env, 0);
}
Keep in mind that you don't need to create a new resource nor return it again if you don't want to, you're modifying the memory pointed by it.
Wrapping a std:vector in a resource
You may have noticed that in the snippets above I used only 'resource' and not 'vector', you have a choice there (my C++ is a bit rusty, though, so take the following with a grain of salt):
You can have the resource hold a pointer to the vector (safest):
typedef struct {
std::vector<MyStructS1>* vector;
} ResourceStruct;
void* pointer_to_resource_memory = enif_alloc_resource(vec1_res, sizeof(ResourceStruct));
pointer_to_resource_memory->vector = new std::vector(...) // std::vector constructor is called here
// TODO 'new' should use enif_alloc(), destroy, enif_free()
or you can have the resource be the vector (I'm not sure if this syntax is allowed, but you get the idea):
void* pointer_to_vector_object_memory = enif_alloc_resource(vec1_res, sizeof(std::vector<MyStructS1>));
// TODO: Somehow initialize a std::vector in the given memory

Convert CComPtr<IShelltem2> to LPWSTR*?

I'm using a variable of type CComPtr and I need to modify a LPWSTR* variable. The function I use extracts metadata about file description for executable files. I am not sure about how I should allocate memory for the LPWSTR* and how to change its value to the one of the CComPtr. lpszFileDesc must get the value of description.
BOOL ExeDescription(LPWSTR* lpszFileDesc, LPCWSTR filePath)
{
CComPtr<IShellItem2> item;
HRESULT hr = CoInitialize(nullptr);
*lpszFileDesc = NULL;
BOOL fResult = TRUE;
hr = SHCreateItemFromParsingName(filePath, nullptr, IID_PPV_ARGS(&item));
if (FAILED(hr))
{
fResult = FALSE;
}
else
{
CComPtr<WCHAR> description;
hr = item->GetString(PKEY_FileDescription, &description);
if (FAILED(hr))
{
fResult = FALSE;
}
else
{
if (!description)
{
*lpszFileDesc = PathFindFileNameW(filePath);
}
else
{
// here I want to copy the contents of description
// into lpszFileDesc but I don't know how
}
if (!*lpszFileDesc)
{
fResult = FALSE;
}
}
}
CoUninitialize();
return fResult;
}
Also, when I call this function how do I deallocate the memory for lpszFileDesc after calling the function?
For example if in wmain() I have:
LPWSTR* lpszFileDesc;
ExeDescription(LPWSTR* lpszFileDesc, LPCWSTR filePath);
How do I deallocate the memory if I don't need the file description after that?
Basic Errors
HRESULT hr = CoInitialize(nullptr);
...
CoUninitialize();
COM should be initialized only once at startup of the thread, because it defines the concurrency model of the thread (amongst other things). It's not up to your function to decide how COM will be initialized for the thread. Once COM is initialized for a thread, subsequent calls to CoInitialize[Ex] within that thread will fail anyway. So remove this code and put it into WinMain or the main function of the thread where you are using COM.
CComPtr<WCHAR> description;
Using CComPtr is wrong here, because IShellItem2::GetString() does not return an interface, but a simple C string. Such "raw" memory allocated by COM API must be freed using CoTaskMemFree(), which can be automated by using CComHeapPtr.
Preferred solution - change the interface
how do I deallocate the memory for lpszFileDesc
Do yourself a favor and use std::wstring instead of raw C string pointer to return a string from your function. The std::wstring destructor takes care of deallocation automatically. Manually managing the memory of C strings is too cumbersome and error-prone. When someone else reads your code and sees std::wstring, there will be no question about how the memory is managed.
I suggest to change your interface like this:
BOOL ExeDescription(std::wstring& fileDesc, LPCWSTR filePath);
... and the assignment within the function body becomes:
if (!description)
{
fileDesc = PathFindFileNameW(filePath);
}
else
{
fileDesc = description;
}
CComHeapPtr<WCHAR> has a conversion operator to WCHAR*, that's why the assignment to std::wstring simply works.
Call the function like this:
std::wstring fileDesc;
ExeDescription(fileDesc, filePath);
// No worries about deallocation of fileDesc!
Solution using original interface
That being said, here is a solution using your original interface. You can either use the COM allocator, as IShellItem2::GetString() already uses it (and there will be no copying in the common case) or use a different allocator (then you always have to copy). In both cases, the caller is responsible to call the right deallocation function, which you have to document (another reason why I would prefer the std::wstring solution).
Example of using the COM allocator:
BOOL ExeDescription(LPWSTR* lpszFileDesc, LPCWSTR filePath)
{
// ... other code ...
// GetString() uses CoTaskMemAlloc() internally
hr = item->GetString(PKEY_FileDescription, lpszFileDesc);
// ... other code ...
if (! *lpszFileDesc )
{
LPCWSTR fileName = PathFindFileNameW(filePath);
// Allocate buffer using the COM allocator and copy fileName to it.
std::size_t const len = wcslen(fileName);
*lpszFileDesc = reinterpret_cast<LPWSTR>(CoTaskMemAlloc(len * sizeof(WCHAR)));
if(*lpszFileDesc)
wcscpy_s(*lpszFileDesc, len, fileName);
}
// ... more code ...
}
Usage at the caller site:
LPWSTR fileDesc = nullptr;
ExeDescription(&fileDesc, filePath);
// ... use fileDesc ...
CoTaskMemFree(fileDesc);
Simplified usage with CComHeapPtr:
CComHeapPtr<WCHAR> fileDesc;
ExeDescription(&fileDesc, filePath);
// ... use fileDesc ...
// Deallocation happens automatically through CComHeapPtr's destructor

fixing the recursive call to malloc with LD_PRELOAD

I am using LD_PRELOAD to log malloc calls from an application and map out the virtual address space however malloc is used internally by fopen/printf. Is there a way I can fix this issue?
I know about glibc's hooks but I want to avoid changing the source code of the application.
My issue was caused by the fact that malloc is used internally by glibc so when I use LD_PRELOAD to override malloc any attempt to log caused malloc to be called resulting in a recursive call to malloc itself
Solution:
call original malloc whenever the TLS needs memory allocation
providing code:
static __thread int no_hook;
static void *(*real_malloc)(size_t) = NULL;
static void __attribute__((constructor))init(void) {
real_malloc = (void * (*)(size_t))dlsym(RTLD_NEXT, "malloc");
}
void * malloc(size_t len) {
void* ret;
void* caller;
if (no_hook) {
return (*real_malloc)(len);
}
no_hook = 1;
caller = (void*)(long) __builtin_return_address(0);
printf("malloc call %zu from %lu\n", len, (long)caller);
ret = (*real_malloc)(len);
// fprintf(logfp, ") -> %pn", ret);
no_hook = 0;
return ret;
}

C++ win32 thread createThread function not passing parameter correctly

So, I have been trying to figure out how c++ multi-threading works and how to apply it to the project I am working on. I am trying to accomplish creating a new thread and running a function on that thread. The function I am trying to run is called SetupInfo and takes an Individual as a single parameter. I have seen examples of this and have tried to implement them, but after multiple attempts I cannot successfully pass the parameter I need into the thread I want the function to run on. Here is what I have come up with:
Here I create a struct to store the pointer to the Individual that I need later on.
struct ThreadData
{
Individual *m_pInd;
ThreadData(Individual pInd) : m_pInd(*pInd) {}
};
Here I create a function that I can call in my program that creates the thread that runs the function SetupThreadFunction which takes a void pointer as a parameter. I am trying to pass the variable data into this function and then cast it back to ThreadData to be able to access the items of the struct.
void SetupThread(Individual input)
{
ThreadData *data = new ThreadData(input);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SetupThreadFunction, data , 0, 0);
delete data;
}
Here I create the function that is passed into the CreateThread function which takes a void pointer and casts it to ThreadData which can then theoretically access the threadData->m_pInd. The same pointer for data above is passed correctly into the SetupThreadFunction. However, m_pInd contains null data and not the pointer to the information that is expected. Why is that?
DWORD WINAPI SetupThreadFunction(LPVOID lpParameter)
{
ThreadData* threadData = (ThreadData*)lpParameter;
SetupInfo(threadData->m_pInd);
return 0;
}
Is there a more correct way to pass a parameter into the new win32 thread I am creating?
The correct pattern is to allocate the object with new, fill in the data (if not done through parameters to new), pass the pointer to the newly-created thread, and let the thread delete the object when it's done with it. You delete the object before you know the thread has even started!
This isn't a multithreading problem; it's a pointer problem.
This line doesn't make sense to me:
ThreadData(Individual pInd) : m_pInd(*pInd) {}
m_pInd is a pointer and yet you're initializing it with *pInd which means you want to dereference pInd, but pInd is not a pointer, let alone a pointer to a pointer. I don't see how this would even compile.
Assuming you actually meant & instead of *, as in:
ThreadData(Individual ind) : m_pInd(&ind) {}
The problem here is that you're creating a pointer to a copy of an Individual on the stack, and that copy goes away upon return from the constructor, so you have a dangling pointer.
Use std::thread.
void ThreadProc(Individual individual);
int main()
{
Individual individual;
std::thread thread(ThreadProc, individual);
thread.join();
return 0;
}
Here's a simple code example to demonstrate the points already discussed.
#include "stdafx.h" // includes <windows.h>, <string> and <iostream>
using std::string;
using std::cout;
class Individual
{
public:
string s;
};
struct ThreadData
{
Individual *m_pInd;
ThreadData(Individual* pInd) : m_pInd(pInd) {}
};
DWORD WINAPI SetupThreadFunction(LPVOID lpParameter)
{
cout << "Hi From Thread\n";
ThreadData* threadData = static_cast<ThreadData*>(lpParameter);
//SetupInfo(threadData->m_pInd);
// do delete here, once its finished with.
delete threadData;
return 0;
}
HANDLE SetupThread(Individual* input)
{
ThreadData *data = new ThreadData(input);
return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SetupThreadFunction, data , 0, 0);
}
int _tmain(int argc, _TCHAR* argv[])
{
cout << "Hi\n";
Individual* i = new Individual;
HANDLE h = SetupThread(i);
if(h)
{
WaitForSingleObject(h, INFINITE);
cout << "Done\n";
} else
{
cout << "Couldnt create thread\n";
}
getchar();
delete i;
return 0;
}
Bear in mind also you can use _beginthread as a simpler interface to launch a thread on Win32.

Exchanging data between Ruby and C++

I've been looking through tutorials on how to embed Ruby into a C++ program. I've found out how to define a class through "rb_define_class" and "rb_define_class_under" and methods through "rb_define_method". Now i need a good example that explains how to wrap an existing C++ object (pointer) with a ruby class written in C++. Example:
class MyClass
{
public:
MyClass();
void MyMethod();
};
VALUE myclass_init(VALUE self)
{
// I'd like to create a new MyClass instance and store its pointer inside "self"
}
VALUE myclass_meth(VALUE self)
{
// Now i need to retrieve the pointer to the object and call its method
}
int main(int argc, char* argv[])
{
ruby_init();
ruby_init_loadpath();
VALUE myclass = rb_define_class("MyWrapperClass", rb_cObject);
rb_define_method(myclass, "initialize", (VALUE(*)(...))myclass_init, 0);
rb_define_method(myclass, "myWrappedMethod", (VALUE(*)(...))myclass_meth, 0);
// Loading ruby script skipped..
ruby_finalize();
return 0;
}
I also need a way to handle garbage collection in order to free my wrapped object (and do other stuff). Sorry for the bad english and thanks to whoever will try to answer this question!
To integrate with Ruby's memory management, you need to implement two functions that allocate and free memory for one of your objects - neither may take parameters. Ruby will store your C++ data structure "attached" to the Ruby self VALUE, and you need to use a couple of methods to create that attachment, and to get at your C++ from self.
Your code so far was close enough that I have just filled in the gaps for you here:
class MyClass
{
public:
MyClass();
void MyMethod();
};
//////////////////////////////////////////////////////////
// The next five are the functions that you were missing
// (although you could factor this differently if you chose)
MyClass *rb_create_myclass_obj() {
return new MyClass();
}
void rb_delete_myclass_obj( MyClass *p_myclass ) {
delete p_myclass;
return;
}
VALUE myclass_as_ruby_class( MyClass *p_myclass , VALUE klass ) {
return Data_Wrap_Struct( klass, 0, rb_delete_myclass_obj, p_myclass );
}
VALUE myclass_alloc(VALUE klass) {
return myclass_as_ruby_class( rb_create_myclass_obj(), klass );
}
MyClass *get_myclass_obj( VALUE obj ) {
MyClass *p_myclass;
Data_Get_Struct( obj, MyClass, p_myclass );
return p_myclass;
}
//////////////////////////////////////////////////////////
VALUE myclass_init(VALUE self)
{
// You need do nothing here, Ruby will call myclass_alloc for
// you.
return self;
}
VALUE myclass_meth(VALUE self)
{
MyClass *p_myclass = get_myclass_obj( self );
p_myclass->MyMethod();
// If MyMethod returns some C++ structure, you will need to convert it
// Here's how to return Ruby's nil
return Qnil;
}
int main(int argc, char* argv[])
{
ruby_init();
ruby_init_loadpath();
VALUE myclass = rb_define_class("MyWrapperClass", rb_cObject);
// The alloc function is how Ruby hooks up the memory management
rb_define_alloc_func(myclass, myclass_alloc);
rb_define_method(myclass, "initialize", (VALUE(*)(...))myclass_init, 0);
rb_define_method(myclass, "myWrappedMethod", (VALUE(*)(...))myclass_meth, 0);
// Loading ruby script skipped..
ruby_finalize();
return 0;
}