I didn't know that...
I didn't know that...
that just like what i have applied in my code as below to retrieve the error message..
But... I always get the same error message as...PHP Code:LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
// Display the string.
MessageBox(hWndMain, (LPCTSTR)lpMsgBuf, "RouteCE", MB_OK | MB_ICONEXCLAMATION);
// Free the buffer.
LocalFree(lpMsgBuf);
'The operation is successful completed' :( why also the same error message?
Quote:
Originally posted by parksie
Oh okay :) I didn't look at the attachment so when you mentioned SEH I got confused.
I don't normally use it, because any FATAL system exceptions will be caught by the normal C++ exception handling:Code:int *ptr = (int*)NULL;
try {
*ptr = 5;
} catch(...) {
cout << "Caught!" << endl;
}
Only Win32 API functions call SetLastError(...) so an access violation or page fault won't.
You can also call SetLastError yourself, but it isn't done by the compiler.
may i know the adv/disadv for shifting part of the code in a project into LIB (*.lib)/DLL(*.dll)? When I shoud use which?
regards,
Basically, they both allow you to reuse the same code in more than one program. A LIB is static, so it's linked directly into the program. This means that it doesn't rely on anything else for it. A DLL also has a LIB associated with it, but this is just a stub to tell it where to find the functions in the DLL.
The problem with DLLs is the usual one ;)
DLL +:
Only once in memory!
Can be updated, recompiled and replaced wtihout having to recompile the application (as ling as the front-end remains the same, the entry points would probably change so this is more a theoretical advantage)
Can be used in more languages (how to use libs in VB or pascal?)
LIB +:
Called faster
Easier to write :)
Included in exe, so shipping is just one file.
There may be more, but that's what comes to mind...
:) thx both Parksie & CornedBee. I get the different now.
:D after long period and I finally found the way to return a string from a VC++ dll to VB application and just woulkd like to share with your guy. :) I also enclose the sample code here...
PHP Code:// DLL External Callback Function Definition
typedef void (CALLBACK* ExSockProc)(UINT msg, long lParam, BSTR bstrBuffer);
// Callback function declaration
ExSockProc MyExSockProc;
BSTR bstr;
// Allocate BSTR buffer
bstr = SysAllocStringLen(NULL, lstrlen(lpszMessage));
// convert from char to BSTR
MultiByteToWideChar(CP_ACP,
0,
(LPSTR)lpszMessage,
strlen(lpszMessage),
LPWSTR(bstr),
lstrlen(lpszMessage));
// Send the error message back to external program
if (MyExSockProc != NULL)
MyExSockProc(SOCKET_SENDCOMPLETE, lstrlen(lpszMessage), bstr);
// Release the used memory
SysFreeString(bstr);
It's been a long time...
Just one more thing: when you know you're dealing with a UNICODE string, you shouldn't use lstrlen but rather lstrlenW or wcslen, because lstrlen will be either lstrlenA or lstrlenW depending on compiler settings.
ic, but the lpszMessage is a char array. Should I proceed to use lstrlenW?
no, wait, I misunderstood your code. It's ok.
Chris,
Great to see you finally got it working. Now I want to ask you a few questions:
- How would you pass a UDT to a VC program, modify the value, and then show it in VB?
- Declare a callback function from vb?? how to use a "function" as the callback and not a "sub"??
I had more, but forgot. But most importantly, this is what killed me:
VB Code:
Public Function Update( strMessage As String, _ intValCode as Long, _ byval intLen as Long ) As Byte ' do some action ' Return 0 as Failure or anything else as success! End Function ' somewhere in code InitiateCPPEvent AddressOf Update ' Error: doesnt work, why?
I just want to know why Functions cant be used as callbacks (or event) as opposed to subs. also, why cant you "modify" the value of a VB UDT?
Regards,
MoMad
Hi Momad, the callback function need not must be a Function, it can be a Sub as well. Since the AddressOf function is just passing the memory location of the respective function/sub into the dll. So that, any need the dll can execute the original function/sub as below:
VB Code:
Public Function Update1( strMessage As String, _ intValCode as Long, _ byval intLen as Long ) As Byte ' do some action ' Return 0 as Failure or anything else as success! End Function Public Sub Update2( strMessage As String, _ intValCode as Long, _ byval intLen as Long ) ' do some action End Sub ' somewhere in code InitiateCPPEvent AddressOf Update1 or InitiateCPPEvent AddressOf Update2
As for the UDT, I'll back to you later :)
Just remember that the callback must be in the main module of your project. And watch out. If any parameter except strings is not explicitely declared as ByVal, you need to use &var in C to pass it.
So your function must be called like:
else you see VB going down with an access violation and this may kill your entire progress if you didn't save.Code:int DllFunc(VBCB pCallback)
{
int i = 4, j = 7;
pCallback(/*string*/, &i, j);
}
Juz include one more function in the sample code:
and in VB will be like...PHP Code:typedef struct tagUSERDATA
{
long Param1;
long Param2;
LPSTR lpszParam3;
} USERDATA, FAR * LPUSERDATA;
extern "C" __declspec(dllexport) void FillUDT(LPUSERDATA UserData)
{
// Fillup the pass in UserData structure
UserData->Param1 = 100;
UserData->Param2 = 201;
sprintf(UserData->lpszParam3, "This is the data return from VC++ DLL through structure.");
}
VB Code:
'// User define data type Private Type tagUSERDATA Param1 As Long Param2 As Long lpszParam3 As String End Type Dim UserData As tagUSERDATA Dim Buffer As String '// Setup the UserData structure Buffer = String(128, Chr(0)) UserData.lpszParam3 = Buffer '// Call the FillUDT funcion FillUDT UserData '// Display the return result MsgBox CStr(UserData.Param1) MsgBox CStr(UserData.Param2) MsgBox UserData.lpszParam3
regards,
thanks, ill look at this later, i lost my connection this weekend.
Chris, I need some help here :rolleyes:
http://www.vbforums.com/showthread.p...hreadid=281510
Whoa, that is SOME old thread you revived...
Hi Gtarawneh,
Yup, it was really a old thread, and you can passing data between 2 application by sending the WM_COPYDATA. With this message, you can passing your own structure.
All you need is to locate the recepient winow handle by FindWindow or FindWindowEx, Also you need to subclass the VB application main window procedure.
Do let me know if you need any sample :)
regards,
Oops! Sorry guys :rolleyes:
Anyway, Chris I think you misunderstood! I am looking for a way to pass my structure into a C++ DLL (Precisely an ATL Com DLL), just the same as you, except that you were using API! Not from one C++ application into another VB application :)
Oops... :rolleyes:
May be you can pass your VB user define type into the ATL COM dll via an interface which the arguement is LPVOID and you have to define the same structure in the ATL COM Dll and cast it back.
regards,