Is it possible to set a custom allocator for OpenCV 2.3.1? I have a memory pool created and I want OpenCV to use that pool for what it needs.
Is that possible?
If it is, how can it be done?
Updated:
I made some developments since last answer, but I still have some problems.
This is the code I have now:
CvAllocFunc allocCV()
{
return (CvAllocFunc) MEMPOOL->POOLalloc(sz);
}
CvFreeFunc deallocCV()
{
return (CvFreeFunc) MEMPOOL->POOLfree(ptr);
}
...
cvSetMemoryManager(allocCV(),deallocCV(),data);
Now, my question is, how can I have access to the size and the pointer to the data I want to allocate and later to deallocate?
Just found out:
The version of OpenCV I'm using (2.3.1) throws an error when using cvSetMemoryManager. The reason is in its source code:
void cvSetMemoryManager( CvAllocFunc, CvFreeFunc, void * )
{
CV_Error( -1, "Custom memory allocator is not supported" );
}
I was very disappointed with this. I guess I can't use a custom memory pool with OpenCV anymore!
Right from the docs
http://opencv.willowgarage.com/documentation/c/core_utility_and_system_functions_and_macros.html#setmemorymanager
Use the
void cvSetMemoryManager(CvAllocFunc allocFunc=NULL, CvFreeFunc freeFunc=NULL, void* userdata=NULL)
function.
Your code
cvSetMemoryManager(allocCV(),deallocCV(),data);
is WRONG.
See what happens: you call allocCV and deallocCV functions (they return some pointer which is quietly converted to cvAllocFunc) !
And this is only the beginning. See the docs for alloc/dealloc semantics. You should write allocCV/deallocCV with correct signatures.
void* CV_CDECL allocCV(size_t size, void* userdata)
{
return ((YourMemPoolTypeWhichIDoNotKnow*)userdata)->POOLalloc(size);
}
int CV_CDECL deallocCV(void* pptr, void* userdata)
{
return ((YourMemPoolTypeWhichIDoNotKnow*)userdata)->POOLfree(pptr);
}
and then pass your MEMPOOL in the 'userdata' parameter:
cvSetMemoryManager(&allocCV, &deallocCV, (void*)MEMPOOL);
This is a standard way for a library to provide user callbacks.
Related
Using Xamarin, I'd like to use an AVAudioSinkNode to store and eventually transfer incoming audio data from a mic at the lowest latency possible (without going straight into AudioUnits and the deprecated AUGraphs). See my commented code below where the SinkNode is connected to the default InputNode. It's giving me grief. I'm using Xamarin.Forms with a simple iOS dependency class. I can successfully hook up an InputNode through an fx node (Reverb for example) and on out to the OutputNode. In this case, I've minimized my code down to focus on the problem at hand:
public unsafe class AudioEngine : IAudioEngine
{
AVAudioEngine engine;
AVAudioInputNode input;
AVAudioSinkNode sink;
public AudioEngine()
{
ActivateAudioSession();
}
protected void ActivateAudioSession()
{
var session = AVAudioSession.SharedInstance();
session.SetCategory(AVAudioSessionCategory.Playback, AVAudioSessionCategoryOptions.DuckOthers);
session.SetActive(true);
session.SetPreferredIOBufferDuration(0.0007, out error); // 32 byte buffer, if possible!
engine = new AVAudioEngine();
input = engine.InputNode; // to save on typing
input.Volume = 0.5f;
var format = input.GetBusInputFormat(0); // used for fx connections, but not used in this snippet. If I use this in the Input -> Sink connection, it crashes.
sink = new AVAudioSinkNode(sinkReceiverHandler);
engine.AttachNode(sink);
try
{
//-----------------------------------------------------
// Param #3 (format) is nil in all the Apple Documentation and multiple examples
// In place of nil, **NSNull.Null** isn't accepted.
// In place of nil, **null** throws a System.NullReferenceException. (see stack dump)
// In place of nil, using the **InputNode's format** crashes with
// something about missing the Trampolines.g.cs file... no clue...
engine.Connect(input, sink, **null**); // null doesn't work in place of nil.
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace); // Exception messages included below
}
engine.Prepare();
engine.StartAndReturnError(out error);
}
private unsafe int sinkReceiverHandler(AudioToolbox.AudioTimeStamp timeStamp, uint frames, ref AudioToolbox.AudioBuffers inputData)
{
// Do stuff with the data...
return 0;
}
}
I found a post related to the use of nil as a parameter in Xamarin.iOS that says the author of the library needs to include the [NullAllowed] argument:
How to assign something to nil using Xamarin.iOS
My question is: Am I missing something obvious, or is this an oversight in the Xamarin library definition? I always assume it's my lack of expertise, but if this is a bug, how do I go about reporting it to Xamarin?
A follow up question: If this is a glitch, is there a viable workaround? Can I go in and tweak the Xamarin library definition manually? (which would break on any updates, I'm sure.) Or can I make a little library using Swift which I then import into my Xamarin project?
Just trying to think of options. Thanks for reading! Below is the Stack dump when I use null as a substitute for nil (again... NSNull.Null isn't considered a valid type in this case. It just doesn't compile):
{System.NullReferenceException: Object reference not set to an instance of an object
at AVFoundation.AVAudioFormat.op_Equality (AVFoundation.AVAudioFormat a, AVFoundation.AVAudioFormat b) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.18.3.2/src/Xamarin.iOS/AVFoundation/AVAudioFormat.cs:27
at AVFoundation.AVAudioEngine.Connect (AVFoundation.AVAudioNode sourceNode, AVFoundation.AVAudioNode targetNode, AVFoundation.AVAudioFormat format) [0x00024] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.18.3.2/src/Xamarin.iOS/AVAudioEngine.g.cs:120
at udptest.iOS.AudioEngine.ActivateAudioSession () [0x0009b] in /Users/eludema/dev/xamarin/udptest/udptest.iOS/AudioEngine.cs:43 }
THANKS!
This has been confirmed as a bug: The format parameter is [NullAllowable], but the current code to actually process that null wasn't linked up in the wrapper code. Here's the issue tracker on the Xamarin.Mac/iOS github repo:
https://github.com/xamarin/xamarin-macios/issues/9267
Thanks for the github issue submission link, #SushiHangover!
I have a lot of native classes that accept some form of callbacks, usually a boost::signals2::slot-object.
But for simplicity, lets assume the class:
class Test
{
// set a callback that will be invoked at an unspecified time
// will be removed when Test class dies
void SetCallback(std::function<void(bool)> callback);
}
Now I have a managed class that wraps this native class, and I would like to pass a callback method to the native class.
public ref class TestWrapper
{
public:
TestWrapper()
: _native(new Test())
{
}
~TestWrapper()
{
delete _native;
}
private:
void CallbackMethod(bool value);
Test* _native;
};
now usually what I would do is the following:
Declare a method in the managed wrapper that is the callback I want.
Create a managed delegate object to this method.
Use GetFunctionPointerForDelegate to obtain a pointer to a function
Cast the pointer to the correct signature
Pass the pointer to the native class as callback.
I also keep the delegate alive since I fear it will be garbage collected and I will have a dangling function pointer (is this assumption correct?)
this looks kind of like this:
_managedDelegateMember = gcnew ManagedEventHandler(this, &TestWrapper::Callback);
System::IntPtr stubPointer = Marshal::GetFunctionPointerForDelegate(_managedDelegateMember);
UnmanagedEventHandlerFunctionPointer functionPointer = static_cast<UnmanagedEventHandlerFunctionPointer >(stubPointer.ToPointer());
_native->SetCallback(functionPointer);
I Would like to reduce the amount of code and not have to perform any casts nor declare any delegate types. I want to use a lambda expression with no delegate.
This is my new approach:
static void SetCallbackInternal(TestWrapper^ self)
{
gcroot<TestWrapper^> instance(self);
self->_native->SetCallback([instance](bool value)
{
// access managed class from within native code
instance->Value = value;
}
);
}
Declare a static method that accepts this in order to be able to use C++11 lambda.
Use gcroot to capture the managed class in the lambda and extend its lifetime for as long as the lambda is alive.
No casts, no additional delegate type nor members, minimal extra allocation.
Question:
Is this approach safe? I'm fearing I'm missing something and that this can cause a memory leak / undefined behavior in some unanticipated scenario.
EDIT:
this approach leads to a MethodAccessException when the lambda calls a private method of its managed wrapper class. seems like this method must at least be internal.
I think that you should not be using gcroot but a shared pointer. Shared pointer are made to keep an object alive as long as someone is using it.
You should also use a more c++ style in your whole code by replacing raw pointer with smart pointer and template instead of std::function (a lambda can be stored in a compile time type).
For example using the code you posted :
class Test
{
// set a callback that will be invoked at an unspecified time
// will be removed when Test class dies
template <class T>
void SetCallback(T callback); // Replaced std::function<void(bool)> with T
}
public ref class TestWrapper
{
public:
TestWrapper()
: _native()
{}
private:
void CallbackMethod(bool value);
std::unique_ptr<Test> _native; // Replaced Test* with std::unique_ptr<Test>
};
After replacing the old method with this new method all over my code base, I can report that it is safe, more succinct, and as far as I can tell, no memory leaks occur.
Hence I highly recommend this method for passing managed callbacks to native code.
The only caveats I found were the following:
Using lambda expressions forces the use of a static method as a helper for the callback registration. This is kinda hacky. It is unclear to me why the C++-CLI compiler does no permit lambda expressions within standard methods.
The method invoked by the lambda must be marked internal so to not throw MethodAccessException upon invocation. This is sort of make sense as it is not called within the class scope itself. but still, delegates / lambdas with C# don't have that limitation.
Sooo...
I have written a plugin, and the whole plugin works fine.
ONLY PROBLEM:
My TS3 Client crashes.
To give a context:
(Warning: That code is just poorly pasted. On GitHub, it crashes at line 270 and 285)
// Helper Function
String^ getChannelName(uint64 serverConnectionHandlerID, uint64 channelID) {
char* tmp;
if (ts3Functions.getChannelVariableAsString(serverConnectionHandlerID, channelID, CHANNEL_NAME, &tmp) == ERROR_ok) {
return marshal_as<String^>(tmp);
}
else
{
return "ERROR_GETTING_CHANNELNAME";
}
}
void assemble_a() {
List<String^>^ clients;
List<String^>^ channel;
// Some middlepart here, but I made sure it works as it should
// And the actual part where it is crashing
if (resChL == ERROR_ok) {
for (int i = 0; channelListPtr[i]; ++i) {
String^ a = getChannelName(schid, channelListPtr[i]);
const char* b = (const char*)(Marshal::StringToHGlobalAnsi(a)).ToPointer();
ts3Functions.logMessage(b, LogLevel_DEBUG, "DEBUG_VC", schid);
if (String::IsNullOrEmpty(a) == false) {
channel->Add(a); // It crashes RIGHT at this point
}
}
}
}
So I am asking on the TS3 forum for a long time, got a lot of answers, and noone could tell me why it actually crashes, and I didn't manage to figure it out on my own either.
It does actually print the channel name [*spacer0]t but as soon as it should append it to the String List, it crashes.
It throws the message The thread has tried to write or read from a virtual address that it does not have the accesspermissions for.
I seriously have no idea what to do, trying to fix it now for over 2 weeks.
For full context: GitHub Sourcecode
Sorry if this question MIGHT be a little out of topic here (Is it? I don't know...) but I don't really know what to do with that problem anymore...
EDIT:
Errormessage from try/catch is:
System.NullReferebceException: The Objectreference was not set to the Objectinstance, occured in tsapi.assembleGrammar()
List<String^>^ channel;
...
channel->Add(a);
channel is null. You need to initialize it with something, probably gcnew List<String^>(). I'm not sure why you're getting an access denied message instead of NullReferenceException.
Other issues
Make sure you're handling all the unmanaged strings properly. For example, does getChannelVariableAsString require a call to explicitly free the buffer? Be absolutely sure to call FreeHGlobal to free the memory that StringToHGlobalAnsi allocated for you.
i am new using c++11 features and also tryng to use SDL_Widget-2 lib for build a simple Gui for my project. But i am getting stuck in the problem :
#include "sdl-widgets.h"
class Builder
{
public:
Builder():top_win(nullptr)
,but(nullptr)
{
top_win=new TopWin("Hello",Rect(100,100,120,100),0,0,false,
[]() {
top_win->clear();
draw_title_ttf->draw_string(top_win->render,"Hello world!",Point(20,40));
}
);
but=new Button(top_win,0,Rect(5,10,60,0),"catch me",
[](Button *b) {
static int dy=60;
b->hide();
b->move(0,dy);
b->hidden=false;
dy= dy==60 ? -60 : 60;
});
}
private:
TopWin * top_win;
Button *but;
};
int main(int,char**) {
Builder aViewBuilder;
get_events();
return 0;
}
with the error in the compilation stage:
In lambda function:
error: 'this' was not captured for this lambda function
error: 'this' was not captured for this lambda function
this error is printed out twice int the console.
I have try :
[this](){}
[=](){}
and
[&](){}
with different compile error but a cannot go more further.
Can any see a fix?
You do need to capture with [this] or [&]. I suspect that the TopWin and Button constructors take raw function pointers, and need to take std::functions instead.
A plain vanilla function pointer is not compatible with capturing lambdas. std::function is able to work like a function pointer that also allows safe storage of captured data. (i.e. the captured objects will need to be properly copied or destroyed when the function object is itself copied or destroyed)
I have a library which exposes callback functions, and needs to be called from both managed and native code. I implemented this by doing:
typedef struct { DWORD blah; } MY_STRUCT;
class ICallbackInterface
{
public:
virtual HRESULT CallbackFunc1(const MY_STRUCT* pStruct) { return S_OK; }
// helper for overriding the vtable (used later on by the managed code)
class VTable
{
public:
void* pfnCallbackFunc1;
};
};
The native code receives a pointer to an ICallbackInterface, and calls CallbackFunc1.
In C++/CLI code, I'm allocating an ICallbackInterface, and overriding its vtable to point to delegates of the managed functions I want to call. (The following snippet is from the constructor):
public ref class MyManagedClass
{
...
m_pCallbackClass = new ICallbackInterface;
if (!m_pCallbackClass)
return E_OUTOFMEMORY;
m_pNewCallbackVtable = new ICallbackInterface::VTable;
if (!m_pNewCallbackVtable)
{
delete m_pCallbackClass;
m_pCallbackClass = nullptr;
return E_OUTOFMEMORY;
}
// Get the (hidden) pointer to the vtable
ICallbackInterface::VTable** ppAddressOfInternalVtablePointer =
(ICallbackInterface::VTable**)m_pCallbackClass;
ICallbackInterface::VTable* pOldVtable = *ppAddressOfInternalVtablePointer;
// Copy all the functions from the old vtable that we don't want to override
*m_pNewCallbackVtable = *pOldVtable;
// Manually override the vtable entries with our delegate functions
m_pNewCallbackVtable->pfnCallbackFunc1 = Marshal::GetFunctionPointerForDelegate(gcnew delCallbackFunc1(this, &MyManagedClass::CallbackFunc1)).ToPointer();
...
And here's the callback function & its delegate
[UnmanagedFunctionPointer(CallingConvention::StdCall)]
delegate HRESULT delCallbackFunc1(const MY_STRUCT* pMyStruct);
HRESULT CallbackFunc1(const MY_STRUCT* pMyStruct)
{
// do something with pMyStruct.
}
}
When I compile the native library for x86, all works well.
(I don't know why CallingConvention::StdCall is used there, but the alternatives seem to cause problems with esp.)
When I compile it for x64, the callback function gets called, and rsp is fine when I return, but pMyStruct is trashed. It appears the native code likes to pass things in to rdx, but somewhere in the native->managed transition (which the debugger won't let me step into), rdx is being filled with garbage.
Is there some attribute I can use to on my delegate to fix this on x64? Or do I need to do something less pleasant like wrap my entire managed class in a native class to do the callbacks? Or did I just find a managed codegen bug?
you're invoking undefined bwhavior left and right, and relying on implementation details such as vtable layout and virtual member function calling convention. it's no wonder that things broke when you changed platforms.
you need to write derived vl lass if the native interface. the implementation can call function pointers or managed delegates directly. and stop messing with the vtsble pointer.
Found the problem.
The managed code has its "this" pointer that comes when initializing the delegate.
But the native function has its own "this" pointer which is being passed along too. Changing the managed signatures to the following totally fixes the bug, and now the function gets access to both "this" pointers.
[UnmanagedFunctionPointer(CallingConvention::ThisCall)]
delegate HRESULT delCallbackFunc1(ICallbackInterface* NativeThis, const MY_STRUCT* pMyStruct);
HRESULT CallbackFunc1(ICallbackInterface* NativeThis, const MY_STRUCT* pMyStruct)
{
// do something with pMyStruct.
}
This works on x86 and x64.