|
Alright guys, thanks for info. So as i see it, to have access to a mem, allocated in dll, so it can bee freed within same dll, i have to make a global variable, like:
wchar_t ****myDB = NULL;
(dllexport)wchar_t ****GetDB()
{
myDB = GetDataBase();
return myDB;
}
(dllexport)void FreeMem()
{
free(myDB);
}
Something like this maybe?
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
If you want to pass blocks of memory around between modules then make sure that whatever module allocated it also frees it. If you don't do that you might end up running into problems with memory being allocated by an allocator specific to one module being returned to another and things going wrong. This means in C calling free from the same library malloc was called from, in C++ it means calling delete from the same module that new was called from [1]. If you're mad enough to be using raw Win32 API calls then whatever called Heap/Global/Local/VirtualAlloc should call Heap/Global/Local/VirtualFree with any required Heap/Global/Local/Virtual[Un]Lock pairs.
There are some other strategies you can use to reduce the chance of an error. One is to write your library so that it doesn't do any memory management. You can do this by either making the client give the library a lump of memory to use or by making the client give a pair of function pointers (functor or interface in C++) to the library - one a pointer to an allocation function, another a poitner to a free/release function. I'd personally go for the first if I were doing cross language calls as the client code can allocate a lump of raw bytes from it's own runtime, give it to a library to play with and then when it's finished consign it to the big bit bucket in the sky. Oh, and make sure that the data structures you're using are plain old data (POD) as different languages have different ideas about what an object is. No idea about C# but Python, for example, can't use C++ objects (and vice versa) without writing a C interface for it.
[1] There are some exceptions - if you're a bit cunning you can get around this rule but it's a good first approximation to say "you allocated it, you release it."
Anyway, hope that helps a bit, if not please shout.
Cheers,
Ash
|
|
|
|
|
Okay, so if it will be, for example, this way (?):
(dllexport)void GetDB(wchar_t ****myDB)
{
myDB = GetDataBase();
}
(dllexport)void FreeMem(void *addr)
{
free(addr);
}
IntPtr myDB = IntPtr.Zero;
GetDB(ref myDB);
FreeMem(myDB);
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
I'd ask if you really need four levels of indirection like that. If you do you'd be just about unique in my experience. Are you sure there's not a structure in there trying to get out?
Ash
|
|
|
|
|
Heh, yeah, i do need such nasty thing. Normally, if i would work all the time in C code, i would use structures in fact, but as i am exporting this whole thing to C# (which is not my primary and in no way beloved language), i stick with wchar_t**** thing, so i know how to easily parse it within C# code without some extra messing around. Export data is a 3D string array, so things went that nasty way
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
Alright, i was so lame.
extern "C"{
__declspec(dllexport)void Stuff(wchar_t *&out)
{
wchar_t *String = L"test string whatever";
out = (wchar_t *)malloc(sizeof(wchar_t *) * wcslen(String) + 1);
wcscpy(out, String);
}
__declspec(dllexport)void FreeMem(void *Ptr)
{
if(Ptr != NULL)
{
free(Ptr);
Ptr = NULL;
}
}
}
[DllImport("testdll.dll")]
public static extern void Stuff(ref IntPtr ptr);
[DllImport("testdll.dll")]
public static extern void FreeMem(IntPtr ptr);
int i = 10000000;
while(i > 0)
{
IntPtr ptr = IntPtr.Zero;
testdll.Stuff(ref ptr);
testdll.FreeMem(ptr);
i--;
}
No crash. Seems to be the best solution so far.
011011010110000101100011011010000110100101101110
0110010101110011
modified on Wednesday, February 2, 2011 7:39 PM
|
|
|
|
|
That is looking good, just a few things I would like to mention:
1. When you modify the value of a parameter, you are only modifying its value within the scope of the function, unless the parameter is passed by reference or you change the value of the pointed to value with a dereference like *p = NULL;
__declspec(dllexport)void FreeMem(void *Ptr) {
if(Ptr != NULL) {
free(Ptr);
}
}
2. sizeof(wchar_t *) * wcslen(String) + 1 is wrong for a few reasons when allocating space for the string.
The +1 needs to be multiplied by the size of each character as well sizeof(wchar_t *) * (wcslen(String) + 1)
Secondly, you need to multiply the number of characters by the size of each character, not the size of the pointer to each character sizeof(wchar_t) * (wcslen(String) + 1)
3. If you allocate a string as an array of wchar_t's rather than a pointer you can get the compiler to hard-code the size in, rather than having to calculate it at runtime.
This only works when the string is known at compile time, as it is in your case.
strlen is a somewhat slow function, it must iterate through every character in the string, check the value of the character and increment a counter. While this is ok if it only happens occasionally, you should prefer to use sizeof() when possible as it gets the compiler to do all this for you.
A similar principal applies for strcpy but to a lesser extent. memcpy can copy the data in chunks rather than 1 character at a time
__declspec(dllexport)void Stuff(wchar_t *&out) {
wchar_t String[] = L"test string whatever";
out = (wchar_t *)malloc(sizeof(String));
memcpy(out, String, sizeof(String));
}
Since you are iterating over this 10,000,000 times (at least in your example) you will notice an increase in performance
Finally, it would be better to return the pointer from Stuff()
__declspec(dllexport)wchar_t *Stuff() {
wchar_t String[] = L"test string whatever";
wchar_t *out = (wchar_t *)malloc(sizeof(String));
memcpy(out, String, sizeof(String));
return out;
}
[DllImport("testdll.dll")]
public static extern IntPtr Stuff();
|
|
|
|
|
Great answer! Thanks very much
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
There are two possible solutions:
1. If the data structure in question is trivial and can be trivially allocated and deallocated, delegate the allocation to the caller. this is what many standard functions such as strcpy() do.
2. If the data structure requires some attention upon allocation, or contains arrays of dynamical (and potentially at the time of creation unknown) length, then the above suggested method is preferable, i. e. you allocate the structure and provide a function to deallocate it appropriately at a later time.
Personally I prefere the first method whereever possible, because it is clearer from the point of view of the caller: it is much easier to spot a missing delete or free that should have been paired with a new or malloc, than spotting a missing call to a deallocation function which should be paired with some "get" or "read" function. It may not be implicitely clear that a function that provides some data also allocates the structure (it might just as well provide a pointer to a structure that is allocated and accordingly freed elsewhere!)
|
|
|
|
|
Title says it all. After all my searching I have not been able to find a decent tutorial or sample code that will teach me how to implement and customize a TabControl function in a Visual C++, Win32, Win32 Project environment. A link or download link to this would greatly be appreciated. Please and thank you.
|
|
|
|
|
You could have put everything into the title itself.
|
|
|
|
|
I think you didn't google it properly. Few of the links I found:
http://www.codeproject.com/KB/tabs/SimpleTab.aspx
http://www.codeguru.com/cpp/controls/controls/tabcontrols/article.php/c7407
http://www.codeproject.com/KB/tabs/AMCustomTabCtrlDemo.aspx
http://www.codeproject.com/KB/tabs/ctabctrlssl.aspx
I haven't gone through the details of the above articles. But after having over look, I can say they might help you to start over (as your problem is not specific. What I've perceived is you just wanna to customize the tab view control).
|
|
|
|
|
I think he was after Win32 API style, not MFC.
|
|
|
|
|
|
If you are wanting to do it with Win32 API and not MFC, I would still suggest checking out the MFC samples that Malli_S linked you to, because it is pretty much the same principal.
See Subclassing a window on MSDN[^]
What you need to do is write your own message procedure for the tab control
WNDPROC g_pOldProc;
LRESULT APIENTRY MyTabProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) {
switch (nMsg) {
case WM_SIZE:
break;
}
return CallWindowProc(g_pOldProc, hWnd, nMsg, wParam, lParam);
}
g_pOldProc = (WNDPROC)SetWindowLong(hTabCtrl, GWL_WNDPROC, (LONG)&MyTabProc);
g_pOldProc = (WNDPROC)SetWindowLongPtr(hTabCtrl, GWL_WNDPROC, (LONG_PTR)&MyTabProc);
You need to restore the old message procedure upon the parents destroy (refer to the sample linked above)
|
|
|
|
|
Hello,
I want to parse the song and video files ....so please tell me anyone how i will do it in MFC.
Ajit K
|
|
|
|
|
Parse a song or video ?
What do you mean by that ? Could you please describe what you are trying to do a bit more clearly ?
|
|
|
|
|
The question sound like:
"I want to elaborate my car engine ... so please tell me anyone how I will do it with my screwdriver."
Do you get the point?
2 bugs found.
> recompile ...
65534 bugs found.
|
|
|
|
|
|
Hello,
Actually i want to get the id of song ,name of song, path of song , duration ,clipinfo if its a video etc using MFC/C++.
Thanks
Ajit
|
|
|
|
|
mozilla firefox will store all bookmarks in places.sqlite file... i am writing small utility which will sync two places.sqlite file bookmarks....
|
|
|
|
|
If I understand your question rgith, there is no need to have any knowledge of the internals in this case.
The easiest thing to do would be to compare the file date and replace the oldest one with the newer.
modified 13-Sep-18 21:01pm.
|
|
|
|
|
no... original file also modified or added with some bookmarks and copied file also modified with some other bookmarks in that we cannot just replace ...
|
|
|
|
|
I'm guessing it's an SQLite database file. Standard procedure is to use SQL. Connect to the database and execute your queries. There are also C APIs[^] for doing this, still needing SQL though. It's well documented and there are plenty of samples around. Use sqlite3_open_v2()[^] to open the file, and sqlite3_exec()[^] to execute your queries.
Good luck!
|
|
|
|
|
I have to add a comment like //<amrit.agrawal> Added 02/02/2011 in somewhere in the code.
When we made some some changes in any file and want to add a tag so that it can be track afterwords to know which developer is made changes on that particular file or line, in a shortcut key like Alt + a.
|
|
|
|