In Java I create some Threads, and they call the same native method like:
public native String go(String str);
In C Language, I have to make an object for each Thread, and the object is only used by each Thread.
Global reference cannot be used because it's shared by all Threads.
I don't want to create the object each time I invoke the JNI method.
How can I implement this?
So you want thread-local Java objects at the JNI side? Just create a ThreadLocal and store it in a global reference.
Related
I create a CwinThread::thread in my application in order to get access to the data in COM asynchronous CALLBACK function.the COM library is initialized by CoInitialize(NULL).
Then when the thread uses the COM object's function an error occurred:
Method call IOPCAsyncIO2::Write failed with error code 8001010e
I use Error Lookup for help:the application is calling an Interface which is organized by another thread
the thread is supposed to be the COM thread.
any ideas?
sorry for not giving you the specific codes few days ago. This time I want to describe my issue using the pseudo code:
first:
in class A,func1
r1 = CoInitialize(NULL);
then something for judgement
in class B(this class is created as a winthread and used for accessing the data from callback class take CallbackClass as example).
in class A,I initialize the thread by calling
m_pThread = AfxBeginThread(RUNTIME_CLASS(CTestThread), THREAD_PRIORITY_NORMAL,0,0,NULL);
calling the functions of Class B by
m_pThread->PostThreadMessage(WM_INITIALIZETHREAD, (WPARAM)this, 0);
one can be aware that the Class A is set for just coding and building the relationship between the dialog, Class B and the CallbackClass.
My question is: I have read many blogs about the MTA and STA, and I know my PC's HKEY_CLASSES_ROOT says the ThreadingModel is Apartment. When I use the Class B(Thread class) to get the pointer of the CallbackClass,there the issue happens.
I know there must be something I missed about my thread and I need some example of at least one COM initialization and one win32 thread and how the thread can get access COM's data.Thank you very much.
So, you're sending a "raw" COM interface ('this') to code in another thread. That's probably why you get the error.
COM interface pointers must be passed using COM methods (as arguments to the method so COM knows it has to marshal it to another thread/apartment), not by other means. When in apartment model, you think of it like every COM object lives in each own process (you can't use 'this' in another process, and that's the same rule for apartments).
You could use "COM Connection points" (see here + google for some explanations: An introduction to COM connection points) which are like events between COM objects. Note this can be complicated.
You could also use more low-level constructs and marshal interface pointers yourself (using the CoMarshalInterThreadInterfaceInStream function). See another article on this here: What are the rules for CoMarshalInterThreadInterfaceInStream and CoGetInterfaceAndReleaseStream?. I would try that first.
is there any common pattern to create singleton objects for each thread?
When I send a sharedInstance message to the singleton class, I expect an instance that is shared only for the currentThread.
Thanks
EDIT: I found this post very useful http://ddeville.me/2011/02/creating-shared-instances-of-non-thread-safe-classes/
A singleton and one object per thread requirement is an contradiction.
You probably want a thread local object. That is one object specific for each thread.
Thread local objects can be implemented by using [NSThread threadDictionary].
There you could store such an object as NSValue which can hold even a pointer.
I have a system that is multi-threaded. I want to create a object in a thread, and every object that runs in this thread can view this object.
Example,
When i use GetCurrentThreadID i always get same id, if i call it from the same thread.
I want to call, for example, getSharedObject and always see the same object if i call it from the same object. So I need to write this object in a memory location that any object inside the same thread can see this object.
Is there anyway to do that, using the Windows API? Or I have to do it by myself?
thanks!
If the variable where you save the object pointer is global, then any code in your thread can access it. And any code from any other thread can, too, for that matter.
If you want that each thread sees a different object, then you want Thread Local Storage.
See the win32 functions TlsAlloc, TlsSetValue, TlsGetValue and TlsFree.
See also __declspec( thread ) here.
What are the differences between creating an instance of a .NET object in C++ that is managed vs. unmanaged. That is to say, what are the differences between these to statements:
StreamWriter ^stream = gcnew StreamWriter(fileName);
versus
StreamWriter *stream = new StreamWriter(fileName);
My assumption is that if I use gcnew, the memory allocated for StreamWriter will be managed by the garbage collector. Alternatively if I use the pointer(*) and new keyword, I will have to call delete to deallocate the memory.
My real question is: will the garbage collector manage the memory that is being allocated inside of the .NET objects? For instance if a .NET object instantiates another object, and it goes out of scope - will the garbage collector manage that memory even if I use the pointer(*) and new keyword and NOT the gcnew and handle(^).
In C++/CLI, you can't new a .NET object, you'll get something similar to the following error:
error C2750: 'System::Object' : cannot use 'new' on the reference type; use 'gcnew' instead
Usage of new for .NET objects is allowed in the older Managed Extensions for C++ (/clr:oldsyntax compiler flag). "Managed C++" is now deprecated because it is horrible. It has been superceded by C++/CLI, which introduced the ^ and gcnew.
In C++/CLI, you must use gcnew (and ^ handles) for managed types and you must use new (and * pointers) for native types. If you do create objects on the native heap using new, it is your responsibility to destroy them when you are done with them.
Ideally you should use a smart pointer (like std::shared_ptr or std::unique_ptr) to manage the object on the native heap. However, since you can't have a native smart pointer as a field of a ref class, this isn't entirely straightforward. The simplest and most generic approach would probably be to write your own smart pointer wrapper ref class that correctly implements IDisposable.
When you create an object with gcnew it is binded to the garbage collector, and the garbage collector will be responsible for destroying it.
If you use new it won't be binded to the garbage collector, and it will be your responsibility to delete the object.
Just to clarify:
If you have a managed C# object that contains within it an unmanaged object, the garbage collector will not delete the unmanaged object. It will just call the managed object's destructor (if it exists) before it is deleted. You should write your own code in the destructor to delete the unmanaged objects you created.
I want a function like GetCurrentThread which returns a TThread object of the current executing thread. I know there is a Win32 API call GetCurrentThread, but it returns the thread Id. If there is a possibility to get TThread object from that ID that's also fine.
From your own answer, it seems maybe you only want to "determine if running in the main thread or not", in which case you can just use
if Windows.GetCurrentThreadId() = System.MainThreadID then
// ...
Although this won't work from a DLL created with Delphi if it was loaded by a worker thread.
The latest version of Delphi, Delphi 2009, has a CurrentThread class property on the TThread class.
This will return the proper Delphi thread object if it's a native thread. If the thread is an "alien" thread, i.e. created using some other mechanism or on a callback from a third party thread, then it will create a wrapper thread around the thread handle.
I'm using my own TThread descendent that registers itself in a global list, protected with a lock.
That way, a method in this descendent can walk the list and get a TThread give an ID.
Answering my own question. I guess it is not possible to get TThread object from ID. It is possible by using a global variable. Then comparing its handle and current thread id, one can determine if running in the main thread or not.
Wouldn't the current executing thread be the one you're trying to run a function from?
You could store the pointer of the TThread instance in the current thread's context via the TlsSetValue API call and then retrieve it using TlsGetValue. However, note that this will only work if you're trying to retrieve/store the TThread instance of the current thread.