I want to use a function that requires me to pass to it as a parameter a void pointer to beginning of a block of memory. The data has to be contiguous in memory for this function to work correctly.
Right now my data is stored in a IVector<IInspectable>. Looking at the memory layout of this IVector in the debugger I see that there is 28 bytes between my data. Which I think are the 7 function pointers from IUnknown and IInspectable. How can I get the underlying contiguous memory allocation of my data?
UPDATE:
Here is the solution I came up with.
Instead of using the IVector<IInspectable> I created a custom vector using the winrt::vector_base as recommended here: https://learn.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/collections
and I wrapped it in a windows runtime component so that I can use this custom vector from C#.
It looks like this:
MyVector.idl
namespace RuntimeComponent1
{
[default_interface]
runtimeclass MyVector
{
MyVector();
void Append(IInspectable in_val);
}
}
MyVector.h
// MyVector.h
#pragma once
#include "MyVector.g.h"
namespace winrt::RuntimeComponent1::implementation
{
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;
struct _MyVector :
implements<_MyVector, IVector<int>, IVectorView<int>, IIterable<int>>,
winrt::vector_base<_MyVector, int>
{
auto& get_container() const noexcept
{
return m_values;
}
auto& get_container() noexcept
{
return m_values;
}
private:
std::vector<int> m_values{};
};
struct MyVector : MyVectorT<MyVector, _MyVector>
{
MyVector() = default;
void Append(Windows::Foundation::IInspectable const& in_val);
};
}
namespace winrt::RuntimeComponent1::factory_implementation
{
struct MyVector : MyVectorT<MyVector, implementation::MyVector>
{
};
}
MyVector.cpp
#include "pch.h"
#include "MyVector.h"
using namespace winrt;
namespace winrt::RuntimeComponent1::implementation
{
void MyVector::Append(Windows::Foundation::IInspectable const& in_val)
{
base_type::Append(winrt::unbox_value<int>(in_val));
}
}
Example usage:
C#
MyRuntimeComponent.MyVector my_vec = new RuntimeComponent1.MyVector();
my_vec.Append(2);
my_vec.Append(4);
MyRuntimeComponent.MyControl my_control = new RuntimeComponent0.MyControl();
my_control.do_stuff_with_contiguous_memory(my_vec);
C++
void MyControl::do_stuff_with_contiguous_memory(RuntimeComponent1::MyVector const& in_data)
{
// Yay data is contiguous
auto contiguous_data = in_data.as<MyVector>()->get_container().data();
}
The end result is that I can pass data from C# to C++/WinRT and the data will be contiguous in C++, which fixes my original problem. It works but I wonder if there might be a simpler / better way?
Related
I am migrating my code from c++17 to c++20 and need to use require instead of std::enable_if...
How to define class constructors as forward declaration with c++20 that uses require keyword on following sample ?
#include <type_traits>
class CChMyBaseClass {
};
template <
typename _ChClass,
typename _ChFunction>
class CChMyClass : public CChMyBaseClass {
private:
_ChFunction m_ChFunction;
public:
// how to do forward declaration ?
CChMyClass()
requires (std::is_member_function_pointer<_ChFunction>::value)
: CChMyBaseClass() {
}
// how to do forward declaration ?
CChMyClass()
requires (!std::is_member_function_pointer<_ChFunction>::value)
: CChMyBaseClass()
, m_ChFunction(
nullptr) {
}
};
class CChTestClass {
public:
void ChTest() {
}
};
void ChTest() {
}
int main() {
CChMyClass<CChTestClass, decltype(&CChTestClass::ChTest)> CChMyClass1();
CChMyClass<CChTestClass, decltype(&ChTest)> CChMyClass2();
return 0;
}
It's really not different from any other type of forward declaration. Just write:
template <typename _ChClass, typename _ChFunction>
class CChMyClass: public CChMyBaseClass {
...
CChMyClass() requires (std::is_member_function_pointer<_ChFunction>::value);
CChMyClass() requires (!std::is_member_function_pointer<_ChFunction>::value);
...
};
I think the difficulty is rather in the actual function definitions. But even that is not too difficult if you think about it. You just need to include the template parameters and the requires clause again:
template <typename _ChClass, typename _ChFunction>
CChMyClass<_ChClass, _ChFunction>::CChMyClass()
requires (std::is_member_function_pointer<_ChFunction>::value)
: CChMyBaseClass(), m_ChFunction(...) {
...
};
Note that in your example, you did not declare two instances of CChMyClass in main(), but rather forward declared two functions that had a CChMyClass as a return type (this is known as the most vexing parse). Just omit the () at the end, or use braces instead.
I have been trying to assign class's member function to a std::function but it throws compile time error Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)
Below is the header file of that class :
class TypeAnalysis {
public:
bool AnalysisHelper(std::string filePath);
void createTypeTable(std::string dir, std::string pattern, size_t nThread = 3);
std::vector<std::string> getFiles(std::string dir, std::vector<std::string> patterns);
private:
};
And below is createtypeTable function where I am assigning AnalysisHelper method to std::fnuction object.
void TypeAnalysis::createTypeTable(std::string dir, std::string pattern, size_t nThread)
{
Threadpool<bool, std::string> tp(10);
DataContext dc;
tp.start();
std::vector<std::string> patterns = SH::split(pattern);
std::vector<std::string> files = getFiles(dir, patterns);
std::function<bool(std::string)> w = &TypeAnalysis::AnalysisHelper; //I think issue is here
try {
if (files.size() > 0) {
for (size_t i = 0; i < files.size(); i++) {
WorkItem<bool, std::string> *wi1 = new WorkItem<bool, std::string>(&w, &files[i]);
tp.doWork(wi1);
}
}
}
catch (std::exception ex) {
std::cout << ex.what();
return;
}
tp.doWork(nullptr);
tp.wait();
DataContext::getContextThreadPool().doWork(nullptr);
}
When I tried to do the same without any class definition (AnalysisHelper was Glabal function and main had same body as createTypeTable), it worked fine.
Any idea whats wrong?
Yes, the problem is in this line:
std::function<bool(std::string)> w = &TypeAnalysis::AnalysisHelper;
I can not see this as correct operation. You are referencing a member function of a class. This member function may need to edit or read one of the member variables of that class. It is not a free function. It is part of the class which should be called for a specific object. So it is normal that C++ denied that.
Edit:
I found this https://isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr
How do I pass a pointer-to-member-function to a signal handler, X event callback, system call that starts a thread/task, etc?
Don’t.
Because a member function is meaningless without an object to invoke it on,
you can’t do this directly (if The X Window System was rewritten in
C++, it would probably pass references to objects around, not just
pointers to functions; naturally the objects would embody the required
function and probably a whole lot more)
Issue was I was not binding the method to any object. Changing
std::function<bool(std::string)> w = &TypeAnalysis::AnalysisHelper;
to
std::function<bool(std::string)> w = [=](std::string file) { return this->AnalysisHelper(file); };
worked.
I apologize if this question is a duplicate - I searched for a while, but it's possible that my Google-fu just isn't up to snuff.
I am modifying a C++ program that calls into a C library. The C library allocates a bunch of memory (using malloc()), and the C++ program uses it and then frees it. The catch is that the C++ program can throw an exception midway through execution, causing the allocated memory to never be freed.
As a (rather contrived) example:
/* old_library.c */
char *allocate_lots() {
char *mem = (char *)malloc(1024);
return mem;
}
/* my_prog.cpp */
void my_class::my_func () {
char *mem = allocate_lots();
bool problem = use(mem);
if (problem)
throw my_exception("Oh noes! This will be caught higher up");
free(mem); // Never gets called if problem is true
}
My question is: how ought I to deal with this? My first idea was to wrap the whole thing in a try/catch block, and in the catch just check and free the memory and re-throw the exception, but this seems graceless and clunky to me (and wouldn't work well if I want to actually catch an exception). Is there a better way to do it?
EDIT: I probably should have mentioned that we're using g++ 4.2.2, from back in 2007 before std::unique_ptr was introduced. Chalk it up to corporate inertia.
Use std::unique_ptr with a custom deleter that calls free:
class free_mem {
public:
void operator()(char *mem) { free(mem); }
};
void my_class::my_func() {
std::unique_ptr<char, free_mem> mem = allocate_lots();
You should make sure that you don't throw until after you have freed the memory - or that you use a suitable smart pointer structure to store the mem, such that when the throw happens, and the stack unwinds, the mem gets freed.
Wrap that rascal:
struct malloc_deleter {
template <typename T>
void operator () (T* p) const {
free(p);
}
};
void my_class::my_func () {
std::unique_ptr<char[],malloc_deleter> mem{allocate_lots()};
bool problem = use(mem.get());
if (problem)
throw my_exception("Oh noes! This will be caught higher up");
}
Since you're using an old compiler version that doesn't have unique_ptr, you can write your RAII wrapper yourself:
class ResourceWrapper {
public:
ResourceWrapper(char* ptr) : m_ptr(ptr) {}
~ResourceWrapper() { free(m_ptr); }
// whatever getters suit you, at the very least:
char* get() const { return m_ptr; }
private:
char* const m_ptr;
};
void my_class::my_func () {
ResourceWrapper mem(allocate_lots());
bool problem = use(mem.get());
if (problem)
throw my_exception("Oh noes! This will be caught higher up");
}
Just make sure not to allow copy/assignment even implicitly (which is why I made m_ptr const) or you'd risk ending up with double-freeing your memory ("move" semantics à la auto_ptr are best avoided unless you absolutely need it).
Since you can't use std::unique_ptr, you could create your own deleter class that would control the lifetime of the pointer in RAII fashion. To keep it simple this example doesn't wrap the actual pointer but exists alongside it; a safer approach would be to make a true smart pointer class.
class AutoFree
{
public:
AutoFree(void* p) : m_p(p)
{
}
~AutoFree()
{
free(m_p);
}
private:
void* m_p;
};
void my_class::my_func () {
char *mem = allocate_lots();
AutoFree mem_free(mem);
bool problem = use(mem);
if (problem)
throw my_exception("Oh noes! This will be caught higher up");
}
Is there any reason not to simply free the memory inside the if clause?
if (problem) {
free (mem);
throw my_exception ("Drat!");
}
Use unique_ptr: http://coliru.stacked-crooked.com/view?id=cd3f0fc64d99cc07a2350e2ff9686500-542192d2d8aca3c820c7acc656fa0c68
#include <stdexcept>
#include <iostream>
#include <memory>
/* old_library.c */
char *allocate_lots()
{
return static_cast<char*>(malloc(1024));
}
struct my_exception : virtual std::exception {
const char* const msg;
my_exception(const char* const msg) : msg(msg) {}
const char* what() const noexcept { return msg; }
};
struct my_class
{
struct Free { void operator() (char* p) const { free(p); } };
/* my_prog.cpp */
void my_func()
{
std::unique_ptr<char, Free> mem;
mem.reset(allocate_lots());
bool problem = use(mem.get());
if(problem)
{
throw my_exception("Oh noes! This will be caught higher up");
}
}
static bool use(char*) { return true; }
};
int main()
{
my_class prog;
prog.my_func();
}
I have the below C struct that has a couple nested structures that have proven to be difficult to deal with using my knowledge of SWIG. Everything below is easily wrapped by SWIG execept for saddr (C socket address) and mac[6] (C array representing a MAC address). Since SWIG gives me the pointer value (SWIGTYPE_p_unsigned_char and SWIGTYPE_p_sockaddr), I would like to somehow call a helper C function to convert the pointer to a char*. I have the helper function, but I don't know the best way to plug this into SWIG. Is there any way to configure the getMac() and getSaddr() to call the helper function?
C Structure Trying To Wrap:
%rename (Details) details_t_;
typedef struct details_t_ {
uint16_t code;
char *name;
**sockaddr *saddr;**
uint32_t saddr_len;
uint8_t flag;
ios_boolean is_child;
**unsigned char mac[6];**
} details_t;
Generated Java Code:
public void setMac(SWIGTYPE_p_unsigned_char value) {
TestJNI.Details_mac_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
}
public SWIGTYPE_p_unsigned_char getMac() {
long cPtr = TestJNI.Details_mac_get(swigCPtr, this);
return (cPtr == 0) ? null : new SWIGTYPE_p_unsigned_char(cPtr, false);
}
public void setSaddr(SWIGTYPE_p_sockaddr value) {
TestJNI.Details_saddr_set(swigCPtr, this, SWIGTYPE_p_sockaddr.getCPtr(value));
}
public SWIGTYPE_p_sockaddr getSaddr() {
long cPtr = TestJNI.Details_saddr_get(swigCPtr, this);
return (cPtr == 0) ? null : new SWIGTYPE_p_sockaddr(cPtr, false);
}
Proposed SWIG.i Changes:
%module Test
%rename (realId) details_t_::mac;
%typemap(javacode) struct details_t_ %{
public String getMac() {
return Test.getMacAddressAsString(this);
//this is a pointer to details_t_ struct
}
%};
%rename (Details) details_t_;
typedef struct details_t_ {
uint16_t code;
char *name;
**sockaddr *saddr;**
uint32_t saddr_len;
uint8_t flag;
ios_boolean is_child;
**unsigned char mac[6];**
} details_t;
You can do this with a javacode typemap, e.g.:
%module test
%rename (realId) Sample::id;
%typemap(javacode) struct Sample %{
public byte getId() {
return 100-getRealId(); // Transform the real call
}
public void setId(byte value) {
setRealId(value+100);
}
%};
struct Sample {
char id;
};
Renames the generated getId() and setId(), but provides a Java get/set which can be written in terms of the SWIG generated (but renamed) one. You might want to make the SWIG generated ones private though.
I've got a problem with using boost::bind and boost::function and passing boost::function as a callback into another class.
Here's an example that is the problematic situation:
typedef boost::function<void (bool)> callbackFunction;
class HasCallback
{
public:
HasCallback() : value(0)
{
}
int value;
void CallBackFunction(bool changed)
{
std::cout << "HasCallback class. CallBackFunction called. Parameter: " << value << std::endl;
}
};
class ReceivesCallback
{
public:
void AddCallback(callbackFunction newFunc)
{
callbacks.push_back(newFunc);
}
void execute(int &i)
{
for(std::vector<callbackFunction>::iterator it = callbacks.begin(); it != callbacks.end(); it++)
{
(*it)(i++);
}
}
void RemoveHandler(callbackFunction oldFunc)
{
for(std::vector<callbackFunction>::iterator it = callbacks.begin(); it != callbacks.end(); it++)
{
if((*it) == oldFunc)
{
callbacks.erase(it);
break;
}
}
}
private:
std::vector<callbackFunction> callbacks;
};
int main()
{
HasCallback hc;
ReceivesCallback rc;
rc.AddCallback(boost::bind(&HasCallback::CallBackFunction, &hc, _1));
hc.value = 123;
HasCallback hc2;
rc.AddCallback(boost::bind(&HasCallback::CallBackFunction, &hc2, _1));
hc2.value = 321;
int a = 0;
rc.RemoveHandler(boost::bind(&HasCallback::CallBackFunction, &hc2, _1));
rc.execute(a);
}
The problem I'm having is that this doesn't even compile. It fails within ReceivesCallback::RemoveHandler in the if((*it) == oldFunc) line with the error saying that there's more than one overload of the operator== for the thing i'm trying to do.
I keep searching for this and can't find what I'm doing wrong. Also, I keep finding contradicting information, one saying that it's possible to compare boost::function-s and another saying it's not. I can see the operator== functions within boost/function_base.hpp and i believe this is supposed to work, I just can't seem to figure out how. Can someone help me out here? My suspicion is that it fails because the parameters of the boost::bind need to be specified fully(be concrete values) but this is something i cannot get in the code I'm developing, I just need to know whether the passed handler is registered or not, since I'm binding to an object it should have all the information neeeded to make the distinction.
See Boost.Function FAQ for an explanation : Why can't I compare boost::function objects with operator== or operator!= ?.
Boost.Functions only provides comparison of a boost::function with an arbitrary function object. I believe that making your RemoveHandler member function template could fix the issue :
template<class Functor>
void RemoveHandler(const Functor &oldFunc)
{
for(std::vector<callbackFunction>::iterator it = callbacks.begin(); it != callbacks.end(); it++)
{
if((*it) == oldFunc)
{
callbacks.erase(it);
break;
}
}
}
Here, oldFunc gets to keep its actual type without being 'wrapped' in a boost::function.