|
Thanks!
Thought i try to explain what i thought of doing. I am writing a DLL and when i tried to use std::basic_string in it i got two unresolved external symbols, _String_base::Xlen and _String_base::Xran. I googled around quite a bit and found out some usefull things, however, the possible solutions i found (reorder the include directories e.g.) either did not make any difference or i did not like them. Mostly people hit this when migrating a project from VS2003 to VS2005 and up, however, i am simply writing a program (not migrating anything) in VS2003 and chanhing to a different VS version is not an option right now.
So, what i have found out is that the problem is caused by mismatching calling conventions. The header file (xstring.h i believe) declares the 2 methods as __thiscall, that is, they are two member methods of __Basic_string, however, the library or DLL (am not sure which here) exports these as static, __stdcall methods, thus, they "can't find each other". So i thought, i could maybe implement the __thiscall versions in my code and in them call the __stdcall versions and live happily ever after. But how i would gain access to the __stdcall versions i don't know, if i could have tricked the system by importing the class with a different name from the DLL (since __Basic_string is already declared i can't use that, and i do not wish to modify xstring.h since that would be ugly at least) i could have declared in this class the __stdcall versions and then call them from the __thiscall versions.
Now i am wondering if i could write a lib file i can link to which imports the right class from the DLL (with the __stdcall versions), exposes two methods for Xran and Xlen (which call their static class member counterparts) and then in my program i could call these in the implementations of the __thiscall versions.
There might be a very simple solution for this which i have simply missed or do not (yet) have enough knowledge (as i said, exporting/importing classes in DLLs is still new to me) to realize and i am re-inventing the wheel.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Life: great graphics, but the gameplay sux. <
|
|
|
|
|
Code-o-mat wrote: So, what i have found out is that the problem is caused by mismatching calling conventions. The header file (xstring.h i believe) declares the 2 methods as __thiscall, that is, they are two member methods of __Basic_string, however, the library or DLL (am not sure which here) exports these as static, __stdcall methods, thus, they "can't find each other"
There is something seriously wrong here if the declaration in the header does not match the implementation in the DLL. Do you have the correct header, are you linking with the correct DLL, are the correct manifest constants defined. As this are standard items provided by Microsoft and used by millions of people, it is unlikely that something is amiss with the code persee. See if there is a static definition of the function in the header, and find out which conditional manifests are required to compile them.
regards,
Bram van Kampen
|
|
|
|
|
Youd didnt tell the aim of that wired idea?
Press F1 for help or google it.
Greetings from Germany
|
|
|
|
|
Actually i did, here[^], but never mind anymore, it turned out later that it was actually a "user error", meaning, i wasn't linking to the right library, stupid me, sometimes one "can't see the woods because of the trees" But thanks anyways.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Life: great graphics, but the gameplay sux. <
|
|
|
|
|
Hello,
My current method of hooking a api function is overwriting (while keeping the old instructions) the start of the function with a jmp instruction and a relative address.
Now I have a question about how to handle cases where the relative jump is larger than 2GB of address.
If I understand correctly this can only happen in 64bit system, right?
So I can test it by:
QWORD *my_address = (QWORD *) &myfunction;
QWORD *original_address = (QWORD *) &orignalfunction;
QWORD jump = my_address - original_address;
if (my_address > original_address && my_address - original_address > 2GB) ||
(original_address > my_address && original_address - my_address) {
//use a 64bit relative jump
}
else {
//use a 32bit relative jump
}
Will this method work on both 64bit and 32bit system/operating systems?
What instruction can use for the above 2gb case? (64bit systems)?
|
|
|
|
|
Well,
I take it that you are fully familiar with Intel I86 assembler code. You must use a 64 bit Jump (jmp64)instruction to jump more than 2GB, which is larger than, and has a different opcode to, the 32 bit equivalent. At the Target of the Jmp, you must replicate all code you overwrote with your jmp64 instruction, and jump back to the first usable opcode after the Jmp64. That can require a bit of doing, in particular if your jmp64 overwrites conditional branches.
BTW I have not yet seen code which exceeds 2 GB. Undoubtedly though, MS will produce something of this size in the future. At least when that happens, you are prepared.
regards,
Bram van Kampen
|
|
|
|
|
Hi
I am using the following createfile function to open a file in network share.
HANDLE file = CreateFile(
File,
GENERIC_READ ,
FILE_SHARE_READ,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
When the file name is \\10.195.1.54\Temp\expample.ini file it is giving error 5.
But when i input the network share name instead of ip like \\Extream\Temp\expample.ini it is opening.
can you please help me what is the problem i am having?
Birajendu
SonicWALL
Bangalore
India
|
|
|
|
|
the system GetLastError API often can tell you about error details especially when you also try to retrieve the rror code and tranlate it into readable text. Use the following snippget of code and tell us what is the message you receive. That case you may be even be able to understand the pbm yourself.
std::string GetFormattedSystemError()
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
char* pMessage = (char*) lpMsgBuf;
return std::string(pMessage);
}
Good luck.
Easy Profiler : a compile-time profiler for C++
www.potatosoftware.com
|
|
|
|
|
birajendu wrote: When the file name is \\10.195.1.54\Temp\expample.ini file it is giving error 5.
Which equates to ERROR_ACCESS_DENIED . Are you sure that the Extream server has an IP address of 10.195.1.54?
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
Yes i am sure about that.cause i can open that loaction through exploler using \\10.195.1.54\temp.
it is not about the perticular extreme server in my Corporate lan. This happens with all PC prsent in Lan, If i try thru the name of the system than it works fine , but though IP it does not work.... No idea why?
I gave a another try.I connected two PC to a router. So here i got IP from router.There is no scenario of DNS here, so i tried trough IP only(some thing like \\192.168.1.2\temp\emaple.ini) and worked perfactly.
SO i am confused where is the problem?
Birajendu
SonicWALL
Bangalore
India
|
|
|
|
|
I've found that calling GdiplusStartup() before CWinThread::Run is called will not work so I have been putting my logic that ensures GdiplusStartup() is called once per app instance in the CDocument constructor.
This worked fine if I only used GDI+ in the CView related code. However, I now have a need to use it as soon as possible during the application initialization.
Does anyone know of a good spot to initialize GDI+ during the application or thread initialization stages?
|
|
|
|
|
When designing CWinApp based applications I always put it in the CWinApp derived constructor.
Best Wishes,
-David Delaune
|
|
|
|
|
Hmmm, there must have been some issue with when to call this in Visual C++ 6.0 using the Platform SDK because I remember it wasn't that easy in those days. I remember trying to call it in various places in the CWinApp derived class but I ended up with some odd errors back then so I got it in my head that I needed to time it properly to avoid conflicts.
I guess this is no longer a problem so I apologize for the question.
thanks for the help.
|
|
|
|
|
This appears to work at first, but if I try to use an open file verb on a data file, I get a "Windows cannot find file (some file path)" error.
This does not happen if I initialize GDI+ later in the process.
NOTE: I'm only using GDI+ in my CView derived OnDraw code during this test.
|
|
|
|
|
I seem to remember putting it into the InitInstance method of my CWinApp derived class.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
That works if I just open the application and then do a File/New or File/Open but if I try to run an open verb on a data file, I get a "Windows cannot find file "Some file path", then the application window opens and the document shows. (The error message box remains somewhere in the z-order.
This does not happen if I don't initialize GDI+ until the CDocument Constructor is called.
|
|
|
|
|
Call Gdiplus::GdiplusStartup() in (CWinApp Derived Class)::InitInstance()
Call Gdiplus::GdiplusShutdown() in (CWinApp Derived Class)::ExitInstance()
|
|
|
|
|
That does not seem to like file open verbs. If I double click on a data file for that MFC application, I get an error "Windows cannot find file (Some file path)".
|
|
|
|
|
What are you talking about? What does GdiPlus have to do with file open verbs?
I created a test MDI application and replicated this behavior. It appears that the GdiPlusStartup causes a problem with DDE. The error is a child window of WindowsExplorer. Even more odd, if you exit the mdi app right after the GdiPlusStartup() call, the error still happens.
This appears to be a Microsoft bug.
modified on Monday, August 17, 2009 3:16 PM
|
|
|
|
|
Joe Woodbury wrote: What are you talking about? What does GdpiPlus have to do with file open verbs?
Thread timing maybe. I dunno. I get the Windows error when I try to double click on an MDI Doc/View application data file when I try to initialize GDI+ where you advised.
It's a mystery to me as well but it is happening.
|
|
|
|
|
Hmm, threw a quick MDI app together and am seeing what you describe. This is a true head scratcher.
|
|
|
|
|
I think I tried suppressing the background thread before and failed but I decided to try this again. This MSDN article appears to discuss the problem but I get a runtime error if I try to implement their code snippet.
Special CWinApp Services[^]
Here on Code Project, this individuals approach to suppressing the background thread (when using GDI+ from a DLL) appears to make the problem go away. I'm not sure what is different about the two since InitInstance is called before CWinThread::Run.
Using GDI+ with MFC or native C/C++[^]
Anyway, thank you for taking some time out to investigate this. We'll see if this approach holds together.
|
|
|
|
|
I got the first solution to run in VS 2005 SP1 with a bare bones app.
I need to store this solution away in my bag-o-tricks.
|
|
|
|
|
Good Monday! (yeah, there goes the sympathy votes!)
I have a small dialog that let the user select one item out of around 250 items.
The items are grouped into logical categories; so I'm looking at doing something like
have two lists, one with the categories, and one containing the subsets represented
by the selected category. (i.e. a bit like the toolbar/command customize of VS2008)
Is there other new ways to present that kind of information ?
Thanks.
Max.
This signature was proudly tested on animals.
|
|
|
|
|
Would a simple tree control do the trick ? Because IMHO it looks better than having two separate lists.
|
|
|
|