I have an unmanaged C++ library. I would like to expose the functionality for .NET applications. There's one partucular function I am not sure how to handle:
typedef void (free_fn*) (void*);
void put (void *data, free_fn deallocation_function);
The idea is that you pass dynamically allocated buffer to the function and supply a deallocation function. The library will process the data asynchronously and will release the buffer later on when data is no longer needed:
void *p = malloc (100);
... fill in the buffer...
put (p, free);
How can I expose this kind of thing to .NET applications?
Be very careful when you do this. .NET really, really wants to have its objects be pinned on the way into an unmanaged routine and unpinned on the way out. If your unmanaged code holds onto a pointer value, that had been pinned on the way in then there is very real chance that the memory will be moved or garbage collected or both.
This is especially the case with delegates marshalled to function pointers (trust me on this - I found that marshaled delegates were being garbage collected on me - I had people at Microsoft verify that for me). The ultimate solution to this problem is to stash away copies of your delegates in a static table paired with a unique transaction id, then create an unmanaged function that when called looks up the delegate in the table via transaction id then executes it. It's ugly and if I had another choice, I would've used it.
Here's the best way to do this in your case - since your unmanaged code uses a set it and forget it model, then you should make your API chunkier. Create an wrapper in managed C++ that allocates memory via an unmanaged routine, copies your data into it and then passes it on along with a pointer to an unmanaged deallocator.
In general, .NET consumers of your library won't be passing dynamically created arrays to your functions. As far as I know, all containers in .NET are garbage collected.
Regardless, you will need to make a managed wrapper for your unmanaged code. There are many tutorials and articles on this, here is one to start with.
When writing .NET wrappers for unamanged code, I've found that you want to concentrate more on preserving functionality than on making every function accessible in .NET. In your example, it may be better to just have the managed wrapper copy the array into unmanaged memory and perform whatever operations you need to inside the library. This way you don't have to do any pinning of managed memory or Marshalling of managed to unmanaged memory in order to circumvent the .NET runtime's garbage collection. However, how you implement the managed wrapper really depends on what the purpose of that function is.
If you really want to implement this function for function in .NET, you will need to look at the Marshal class in .NET for taking control of managed memory in unmanaged code.
For your callback function, you will first need to create .NET delegates that can be assigned in managed code. You will then need to make an unmanaged free function internal to your library that is called by the unmanaged version of the put function. This unmanaged free function will then be responsible for calling the managed delegate, if the user assigned one.
You definitely don't want to pin the managed buffer, as trying to deallocate it in unmanaged code seems like the shortest route to madness. If you can't rewrite this portion in fully managed code, your best bet is either going to be making a copy of the data in the wrapper, or completely hiding the buffer management from the managed world.
If you had the guts (and the masochistic stamina) you could pin the buffer in the wrapper, then pass in the marshaled delegate of a managed function that unpins the buffer. However, I wouldn't suggest it. Having had to do a couple of managed wrappers has taught me the value of exposing the absolute minimum unmanaged functionality, even if it means you have to rewrite some things in managed code. Crossing that boundary is about as easy as going from East Germany to West Germany used to be, to say nothing of the performance hits.
Most replies suggest that the data should be copied from managed buffer to unmanaged buffer. How exactly would you do that? Is following implementation OK?
void managed_put (byte data_ __gc[], size_t size_)
{
// Pin the data
byte __pin *tmp_data = &data_[0];
// Copy data to the unmanaged buffer.
void *data = malloc (size_);
memcpy (data, (byte*) tmp_data, size_);
// Forward the call
put (data, size_, free);
}
Some of the previous poster's have been using MC++, which is deprecated. C++/CLI is far more elegant of a solution.
The BEST, technique for interop, is implicit interop, not explicit. I dont believe anybody has commented on this yet. However, it gives you the ability to marshal your types from managed<->native where if you make a change to your type definition or structure layout, it will not result in a breaking change (which explicit interop does).
This wikiepedia article documents some of the differences and is a good starting point for further information.
P/Invoke (explicit and implicit)
Also, the site marshal-as.net has some examples and information as to this newer method (again, more ideal as it will not break your code if the a native struct is re-defined).
You'd have to have managed wrappers for the functions themselves (or unmanaged wrappers if you want to pass in managed functions). Or else, treat the unmanaged function pointers as opaque handles in the managed world.
Since you mentioned it was asyncronous, I'd do it this way.
The .Net exposed function only takes the data but doesn't take a delegate. Your code passes the pinned data and a function pointer to a function that will simply unpin the data. This leaves the memory cleanup to the GC, but makes sure the it won't clean it up till the asyncronous part is done.
Related
I'm designing a JNI interface that passes string parameters from Java to C++. I need high performance and have been able to use Direct ByteBuffer and String.getBytes() to do that fairly well, but the penalty for passing strings to C/C++ still remains fairly high. I recently read about the Open JDK's Unsafe class. This excellent page got me started, but I'm finding Unsafe to be woefully, but understandably poorly documented.
I'm wondering, if I use the Unsafe class to obtain a pointer to a string and pass it to C++, is there a risk that the object has moved before the C++ code is entered? And even while C++ is executing? Or are these addresses provided by the Unsafe code somehow pinned? If they aren't pinned, how are these Unsafe pointers ever useful?
Unsafe is not meant to interop with JNI. So obtained via Unsafe could change any time (even in parallel with your C++).
JNI API has ability to pin object in memory to access array content (in HotSpot JVM it would block GC thus may have negative effect on GC pause duration).
In particular, Get*ArrayElements would pin array until you explicitly do Release*ArrayElements. GetStringChars work similar way.
Direct ByteBuffer hold pointer to memory buffer outside of heap, hense this buffer is not moving and you can access it for Native code.
I've read the Java source for java.misc.Unsafe and have a bit more insight.
Unsafe has at least two ways of dealing with memory.
allocateMemory/reallocateMemory/freeMemory/etc -- As far as I can tell this allocation of memory is outside the heap so faces no GC'ing challenges. I have indirectly tested this and it seems that the long returned is simply a pointer to the memory. It seems very likely that this type of memory is safe to pass through JNI to native code. And the application Java code should be able to quickly modify/query it before and after JNI calls by using some of the other intrinsic Unsafe methods that support this style of memory pointer.
object+offset - These methods accept a pointer to an object and an "offset" token to indicate where in the object to fetch/modify the value. The objects presumably are always in the Java heap, but passing the object to these methods probably helps resolve GC complications. It does sounds like the "offset" is sometimes a "cookie" rather than an actual offset, but it also sounds like that in the case of arrays, arrayBaseOffset() returns an "offset" that one can manipulate arithmetically. I don't know if this object+offset is safe for JNI code. I don't see a method to generate a pointer directly to the Java object in the heap that one could (dangerously) pass through JNI. One could pass an object and offset, but given the cost of passing Objects through JNI, this approach is not appealing anyway.
Like (1), the code associated with the page I referenced in my posting is probably pretty safe for JNI interactions. It takes the object+offset approach when dealing with String, but uses approach (1) when dealing with the direct ByteBuffer, which always reside outside the Java heap. Direct ByteBuffer's are very JNI friendly and often they can be used in ways that avoids the JNI Object passing costs I allude to in my comment to Tom above.
Sometimes it's convenient to split interface of some system/library in more than one class.
For example, consider idea of library for playing Chess. Its interface would use (and deliver to players) different object for every single game and - during game - another object for every figure.
In Java there wouldn't be such a problem. But in C++, a library user can delete (or make attempt to delete) every pointer he'll get. Even shared_ptr/weak_ptr.
What do you think about such situations? Should I use in my interface wrapping classes that deleting isn't dangerous?
What is an usual way for such dilemmas?
Is there a way that STL smart pointers would help? I heard that they should be used always and only to express ownership, so they seem to have nothing to do with this issue (Chess is owner of SingleGame, SingleGame is owner of every Figure).
PS did I use correct tags/subject?
You can't stop a user from breaking stuff. As others have suggested, use smart pointers. With C++11, there is no reason not to use them in new code. If the user still breaks it, that's their fault. You can't design a library that is completely foolproof. You can just do your best to disuade foolish behavior.
As others have said, smart pointers (or other RAII schemes) are often a great idea. They can clearly indicate ownership and at the same time provide an automatic mechanism for managing it. Try using such if you can.
But really, no reasonable C++ programmer should be blindly calling delete on every pointer they get. When they use a library/API/whatever which returns a pointer/handle/resource/etc they should be reading its documentation to tell them whether or not they will be responsible for deallocation and if so then when technique should be used.
So at a minimum, just make sure your public interface clearly indicates when ownership is passed to the caller and what method they should use for cleanup.
I'm porting a lot of math. I'm using over to c++ from java and seeing a great performance boost from doing so but I cant figure out what jni function to use in order to get rid of variables that I don't need anymore. For instance I know that when your jni method comes to it end and you've been using jfloatArray you call :
env->ReleaseFloatArrayElements(vec,in,0);
And that would destroy the array and free up memory. I'd like to be able to do the same with single primitives that aren't array types if possible but I've looked through the oracle and sun docs and there is no methods to do such a thing......should I just use the default way to destroy objects using c++ or is there a safe sure fire way to do such a thing.
There's nothing necessary. You only have to clean up in cases where the
JNI interface may have allocated memory or other resources. Basic
types, like jfloat , are typedef's for basic C++ types (usually,
float), and are passed around by copy; when you declare a jfloat,
it's just a floating point type on the stack, and disappears when you
leave its scope. The types you have to clean up will normally be
pointers; the clean-up functions are there to free up the memory the
pointer points to.
I'm writing an abstraction layer on top of some graphics API (DirectX9 and DirectX11) and I would like your opinion.
Traditionally I would create a base class for each concept I want to abstract.
So in typical OO fashion I would have for example a class Shader and 2 subclasses DX9Shader and DX11Shader.
I would repeat the process for textures, etc... and when I need to instantiate them I have an abstract factory that will return the appropriate subclass depending on the current graphics API.
Following RAII, the returned pointer would be encapsulated in a std::shared_ptr.
So far so good but in my case there are a few problems with this approach:
I need to come up with a public interface that encapsulate the functionality of both APIs (and other APIs in the future).
The derived class are stored in separate DLLs (one for DX9, one for DX11 etc...) and having a shared_ptr to them in the client is a curse: on exit the graphic dlls are unloaded and if the client still has a shared_ptr to one of the graphics objects boom, crash due to calling code from unloaded DLL.
This prompted me to re-design the way I do things:
I thought I could just return raw pointers to the resources and have the graphics API clean after itself but there's still the issue of dangling pointers on the client side and the interface problem.
I even considered manual reference counting like COM but I thought that would be a step backwards (correct me if I'm wrong, coming from the shared_ptr world, manual reference counting seems primitive).
Then I saw the work of Humus where all his graphics classes are represented by integer IDs (much like what OpenGL does).
Creating a new object only returns its integer ID, and stores the pointer internally; it's all perfectly opaque!
The classes that represent the abstraction (such as DX9Shader etc...) are all hidden behind the device API which is the only interface.
If one wants to set a texture, it's just a matter of calling device->SetTexture(ID) and the rest happens behind the scenes.
The downfall is that the hidden part of the API is bloated, there is a lot of boiler plate code required to make it work and I'm not a fan of a do-it-all class.
Any ideas/thoughts ?
You say that the main problem is that a DLL is unloaded while still having a pointer to its internals. Well... don't do that. You have a class instance, who's members are implemented in that DLL. It is fundamentally an error for that DLL to be unloaded so long as those class instances exist.
You therefore need to be responsible in how you use this abstraction. Just as you need to be responsible with any code you load from a DLL: stuff that comes from the DLL must be cleaned up before you unload the DLL. How you do that is up to you. You could have an internal reference count that gets incremented for every object the DLL returns and only unload the DLL after all referenced objects go away. Or anything, really.
After all, even if you use these opaque numbers or whatever, what happens if you call one of those API functions on that number when the DLL is unloaded? Oops... So it doesn't really buy you any protection. You have to be responsible either way.
The downsides of the number method that you may not be thinking about are:
Reduced ability to know what an object actually is. API calls can fail because you passed a number that isn't really an object. Or worse, what happens if you pass a shader object into a function that takes a texture? Maybe we're talking about a function that takes a shader and a texture, and you accidentally forget the order of the arguments? The rules of C++ wouldn't allow that code to even compile if those were object pointers. But with integers? It's all good; you'd only get runtime errors.
Performance. Every API call will have to look this number up in a hashtable or something to get an actual pointer to work with. If it's a hashtable (ie: an array), then it's probably fairly minor. But it's still an indirection. And since your abstraction seems very low-level, any performance loss at this level can really hurt in performance-critical situations.
Lack of RAII and other scoping mechanisms. Sure, you could write a shared_ptr-esque object that would create and delete them. But you wouldn't have to do that if you were using an actual pointer.
It just doesn't seem worthwhile.
Does it matter? To the user of the object, it is just an opaque handle. its actual implementation type doesn't matter, as long as I can pass the handle to your API functions and have them do stuff with the object.
You can change the implementation of these handles easily, so make it whatever is easier for you now.
Just declare the handle type as a typedef of either a pointer or an integer, and make sure that all client code uses the typedef name, then the client code doesn't depend on the specific type you chose to represent your handles.
Go for the simple solution now, and if/when you run into problems because that was too simple, change it.
Regarding your p. 2: Client is always unloaded before libraries.
Every process has its library dependency tree, with .exe as tree root, user Dll at intermediate levels, and system libraries at low level. Process is loaded from low to high level, tree root (exe) is loaded last. Process is unloaded starting from the root, low-level libraries are unloaded last. This is done to prevent situations you are talking about.
Of course, if you load/unload libraries manually, this order is changed, and you are responsible to keep pointers valid.
I have just started at a new job. Here we are new to using JNI ( for bridging C++ / Java ). I am new to JNI so please forgive my noobness :)
In our (win32) Java app we are loading a C++ DLL. On the Java side we have several instances of "SomeJClass" each of these instances needs access to corresponding instance of "SomeCClass" on the DLL side.
The DLL exposes entry-points such as GlobalDoSomethingInC(). Here I must call the instance method of Doer::DoSomethingInC(). So I need a smooth way to map the respective this-pointers.
I also need to do the same mapping when a DLL thread discovers something interesting that it needs to notify the corresponding Java-instance of.
I can think of several solutions, but I do not like them too much. My question is, is there a better way than this ?
1 Java calls C:GetNewInstance(). This returns an int that is actually a pointer to the new C instance. Java stores it in m_myCInstance. Then Java calls GlobalDoSomethingInC(), and
1a
// DLL global
void GlobalDoSomethingInC()
{
// retrive this pointer
//calling back to Java:
jobj tmpJ = NewGlobalRef( env, obj );
Doer* myDoer = <reinterpret_cast>( Doer )tmpJ->GetMyCInstance();
myDoer->DoSomething();
DeleteGlobalRef( env, tmpJ );
// Arrrrgh
}
1b or:
// for **every call** that Java adds a parameter,
//which is the stored int:m_myCInstance, and
Doer* myDoer = <reinterpret_cast>( Doer )instanceParam->DoSomethingInC();
// Can we do better that this?
2 For calling from C to Java, things look, maybe, better
In the constructor C calls back into Java and stores
the Java instance reference
in a member variable. m_myJInstance.
In all subsequent calls m_myJInstance can be used to call back Java.
In the destructor we need to call DeleteGlobalRef( env, m_myJInstance );
Not too bad I suppose. But it really safe to store the jobject reference.
I mean: What happens when the GC moves the object around?
3 Our present solution does "work". But it belongs on rather on http://www.codinghorror.com/blog/ :)
Thanx
Typically this will depend on your environment somewhat. I've only used KNI, which is even more primitive than JNI. I think a fair bit of ugliness is unavoidable, as you're mixing memory tracking across two systems, only one of which has GC.
In general, I found it best to wrap all of the calls out the C code in functions that took care of the nasty casting, which I think is unavoidable. (BTW, I'll use C to mean non-Java code here)
On the C side, movement of Java objects is definitely a potential problem. It will depend on your platform, but I would expect that as long as you are within the lib, you can expect no Java GC to occur, so your objects are stable. YOU NEED TO BE SURE OF THIS. On the other hand, if it's not the case, you're pretty much screwed. Assuming it is the case, you want to do the same thing of isolating dereferencing/casting to the function that's exposed to JNI, so that you can happily work with normal C objects in all of your called functions.
Where it can get really ugly is if you can have objects go out of scope on either side, as then potentially either side can be holding a reference to your object. Here we used finalizers on the Java side, as well as destructors on the C side. It wasn't pretty, but I think that what somewhat unavoidable.
So, short answer, it will be somewhat ugly, isolate the ugliness around the interface between the two languages, so that for the bulk of the work, in either language, you don't have to worry about such things.
It's also worth having a base class for objects that exist over this interface, as here you can also isolate some ugliness.
jobject is an opaque handle to an object. May vary in runtime implementation (see Android 2.x vs 4.x), but just trust that it is an opaque object.
The current solution is probably correct. If you must stash a jobject in native code, you must convert it to a Global reference -- If you call NewGlobalRef, the object's refcount has increased, and will not be disposed until you call DeleteGlobalRef (and the GC has noticed it is unreachable otherwise)