|
Hi SNArruda,
This is possible if function you want to call is of dll.
You can use GetProcAddress [^] along with LoadLibrary[^]
regards,
Divyang Mithaiwala
Software Engineer
|
|
|
|
|
Divyang's answer is a good one - if the function you want to call is in a DLL.
There is no "execute" command like there is in BASIC. You'll have to roll your own.
int Fred ()
{
return 1;
}
int Wilma ()
{
return 10;
}
int HowHotIs(char *szName)
{
if (!lstrcmpi (szName, "fred"))
return Fred ();
if (!lstrcmpi (szName, "wilma"))
return Wilma ();
return -1;
}<pre>
and call with:
<pre>HowHotIs("Fred");
HowHotIs("Wilma");
HowHotIs(szTextFromFile);
That's a brute force approach. More elegantly, you could have a CString to function pointer map class, or take the approach of self-registering classes from this article: Enumerate your leaf classes[^].
But as you're asking your question, you may want to stick with the brute force approach to start with. But read the article - it's very good! And if you're happy with maps / function pointers - go wild. It's better and more flexible than the function I wrote above.
Iain.
ps: Other ways exist - I've just giving 3.
In the process of moving to Sweden for love (awwww).
If you're in Scandinavia and want an MVP on the payroll (or happy with a remote worker), give me a job!
|
|
|
|
|
Alright, I'm trying to wrap a server written in c for the most part in a class. From inside one of the methods I want to launch a thread to another method. My attempt looks something like this:
void WebServer::ListenServer(void)
{
unsigned threadID;
while(true)
{
int fromlen = sizeof (from);
messageSocket = accept (listenSocket, (struct sockaddr*)&from, &fromlen);
if (messageSocket != INVALID_SOCKET)
{
_beginthreadex(NULL, 1000, (void*)&WebServer::HandleRequest, NULL, 0, &threadID);
}
}
}
void WebServer::HandleRequest()
{
}
Can this even be done? I have tried multiple castings etc of the beginthreadex() function. What would be an alternative to this?
|
|
|
|
|
Hi, from the code you posted I can't be certain if WebServer::HandleRequest is a static function or not. But it must be a static function.
This is because the 3rd argument of _beginthreadex is a pointer to function, which must have exactly the same parameters and return type as the the function that is required.
In this case the function you supply must look like this:
unsigned __stdcall ThreadProc(void * param);
It MUST return an unsigned, and it MUST accept a void* as parameter, and it MUST NOT be a member function. You can still make it part of the class, but as a static function.
Also, never try to fool the compiler by casting the function pointer you pass as your callback - your program is going to try to execute this code, giving it the parameters it expects the function requires. So what if you cast a function that requires more parameters as one that requires less? It will get its arguments from uninitialized memory and will probably crash or cause memory corruption.
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
This article[^] should explain a) why you can't use a bare method pointer as a Win32 callback, and b) help you make an adaptor that will let you call the method you want.
It even mentions _beginthreadex !
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
OK, I have had my head in the sand.... I use VS 6 SP5 MFC. I maintain a legacy application which Vista has broken.
Currently I am using Codejocks Extreme toolkit Automatically linking with ToolkitPro1010vc60SD.lib
I have upgragrated to the latest, but not yet tried a build (too much other stuff going on).
My SDK libs are probably old. I understand the issues with UAC and MS's Stupid vituraliztion scheme unless you have a manifest entry telling them you know about UAC. I also understand their renaming the directory stuctures.
Years ago when they were pushing their com tecnology I bought in and split my program (500k+ lines of code) into several different EXEs which communicate with each other via COM.
Big mistake. Anyway, I won't rant. Back then they preached that you should write to the registry all the time (each time you started to make sure it hadn't gotten corrupted, so all my exe's have something like this in them)
//-----------------------------------------------------------------------------
//Check to make sure we have write permissions to the registry. If we don't, don't
//attempt to register. We won't have write permissions if we are running on
//Windows 200 or XP as a limited user.
LONG lResult = ::RegCreateKeyEx(HKEY_CLASSES_ROOT,sDocClass, 0, "", REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS, NULL,&hTestKey, NULL);
if ((ERROR_SUCCESS == lResult) && (hTestKey != NULL))
{
g_bLimitedUser = FALSE;
//-------------------------------------------------------------------------------------
// It's ok to call UpdateRegistry
m_server.UpdateRegistry(OAT_DISPATCH_OBJECT);
COleObjectFactory::UpdateRegistryAll();
//-------------------------------------------------------------------------------------
BOOL bResult = AfxOleRegisterTypeLib(m_hInstance, LIBID_NTUExplorer);
if (bResult == 0)
{
AfxMessageBox("AfxOleRegisterTypeLib Failed");
}
//-------------------------------------------------------------------------------------
if (RegisterComponents() == FALSE)
{
CString sCaption = BuildVerString2() + "Unrecoverable Error";
CString sError = "Unable to Register Components. Aborting Launch!!!";
SafeUserNotification(sError,sCaption);
if (g_pMainFrame)
g_pMainFrame->PrepareToClose();
return FALSE;
}
}
OK, so Vista comes along and
//Windows 200 or XP as a limited user.
LONG lResult = ::RegCreateKeyEx(HKEY_CLASSES_ROOT,sDocClass, 0, "", REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS, NULL,&hTestKey, NULL);
succeeds but
BOOL bResult = AfxOleRegisterTypeLib(m_hInstance, LIBID_NTUExplorer);
Fails. I hesitate to update the SDK because I am running VS 6 and things are very stable... Who knows what might crop up.
SO, as I see it, I have a couple of options...
Move all my registration to the install program as they now suggest (contratry to previous suggestions) add the manifest entry, dink with my directory structure and things will probably work, although VS 6 doesn't officially run on Vista (I have gotten it installed and it seems to run OK)
or
Bite the bullet, move to VS2008, regen my skeleton apps. Populate them with my code and Deal with the ansi compiler issues and hope for the best....
Any thoughts on what you would do? I have tried .net, 2003, 2005, and pitched them all in favor VS6. If you are a MFC developer there is little reason to move to those platforms... What about VS 2008?
|
|
|
|
|
Having many years of code successfully working and made in VC6, I still use it most days - and quite happily. Mind you, if I could still use Word 6 I would - lightweight, just what I need and not too much extra.
I am a little puzzled at your logic of NOT registering your COM objects in the registry as part of the setup process. That makes only the setup program need any sort of privilege - and you need a lot less privilege for the day to day running of your software.
So, all vista is doing is enforcing behaviour that should have been followed from the beginning.
Would it be a huge change to move the registration code to the setup and comment it out on your "real" programs?
Iain.
In the process of moving to Sweden for love (awwww).
If you're in Scandinavia and want an MVP on the payroll (or happy with a remote worker), give me a job!
|
|
|
|
|
I do register them in the install program.
MS also recommended at the time that you also register in InitInstance to make sure nothing in the registry had gotten corrupted....
Now not suprisingly they recommend the opposite.
I guess the real question is, given the issues with the compiler differences and the fact that I have a large code base, is it worth moving to VS2008, or patch the programs to run on vista and stick with VS6?
So which is better VS2008 or VS6.
Is it worth the move?
|
|
|
|
|
Not a simple problem you have.
I don't think you need to update the registry every time. If a user is stupid enough to delete your entries from the registry, then you'll get com errors and you'll have a chance to write a pithy and sarcastic message box.
AfxMessageBox (L"Please hit yourself. You deserve it. Really...");
The advantage of the way you've broken up your program is that you can slowly migrate - just one exe at a time, rather than all or nothing.
If you can tweak your current VS6 (which I use happily) codebase to work under Vista, then do new development work in later versions.
Parker M cCauley wrote: So which is better VS2008 or VS6?
Both!
Iain.
In the process of moving to Sweden for love (awwww).
If you're in Scandinavia and want an MVP on the payroll (or happy with a remote worker), give me a job!
|
|
|
|
|
I like the message box Idea.... LOL
Unfortuately, back then the theory was that some other program (like the operating system would be the culprit.
Back when I first started looking into it, I was able to find the original KB article that highly recommended you do this, and also the later KB article that says it's a bad idea.
My more recent searches on msdn don't turn up the first. Perhaps it has been removed.
I am interesting it your Both! comment....
Why both?
Do use visual assist with VS6?
|
|
|
|
|
By Both, I meant installing both environments. For the odd tweak, leave your code in VS6. If you have to do major changes to a module, take that chance to modernise it.
While having your code split into bits may give you headaches, it does have the advantage of being able to be converted module by module, instead of all or nothing.
I hope that's more clear.
In the process of moving to Sweden for love (awwww).
If you're in Scandinavia and want an MVP on the payroll (or happy with a remote worker), give me a job!
|
|
|
|
|
OK, thanks for the clarification...
-Parker
|
|
|
|
|
I have been searching the internet for days trying to figure this out and the only thing I can find is other people with this problem and no resolution.
I am writing a C++ application that does not require .NET of any kind.
I can get the currently logged in users information using the NetWkstaUserGetInfo() API call. I then pass the username and domain to the NetUserGetGroups() function and can get back the groups that the user is a member of, but it doesn't show nested groups.
Example:
Group 1
|____Group A
|____*User1*
Group 2
|____Group B
|____*User1*
If a user, *User1*, is a member of "Group A" and a member of "Group 2" I would like for the function to return:
Group A (explicit membership)
Group 1 (implicit membership thru Group A)
Group 2 (explicit membership)
Right now it is only showing:
Group A (explicit membership)
Group 2 (explicit membership)
Please tell me someone has done this before without .NET!
|
|
|
|
|
See here.
"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
|
|
|
|
|
Dude I award you the Googling MOFO of the day trophy!
Of course not if you have that URL tattooed on the back of your hand.
|
|
|
|
|
union u
{
char ch[2];
int i;
};
int main()
{
union u x={0,2};
cout<<x.ch<<"\n\n\n";
cout<<x.i<<endl;
return 0;
}
Why does this print 512??? What is this x={0,2}; exactly doing?
----------------------------
286? WOWW!
|
|
|
|
|
The union looks something like this:
-----------------------
| 512 |
-----------------------
| 00000010 | 00000000 |
-----------------------
| 2 | 0 |
-----------------------
"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
|
|
|
|
|
Thanks.
----------------------------
286? WOWW!
|
|
|
|
|
Is doing politely what you asked with your code.
The character array and the integer share the same memory space (at least the first two bytes), hence assigning one of the two will affect the other (you know that: it is a union , after all... ).
_8086 wrote: union u x={0,2};
Here the compiler initialise the ch member (this surpised a bit me) of the union with the characters having ASCII codes 0 and 2 . Incidentally 0 corrensponds to string terminator so ch eventually contains an empty string, this explains the output of the
_8086 wrote: cout<<x.ch<<"\n\n\n";
line.
Such a initialization affect also the integer (i ) member, and since you computer is a little endian one, you get 0 * 2^0 + 2 * 2 ^ 8 = 512 .
This explains the output of the
_8086 wrote: cout<<x.i<<endl;
line.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Such a small thing has got this much hidden! That's all about that crazy union . Thanks mate.
----------------------------
286? WOWW!
|
|
|
|
|
_8086 wrote: That's all about that crazy union
Farout
|
|
|
|
|
lol
----------------------------
286? WOWW!
|
|
|
|
|
Unions are powerful things, but until you realise that the parts share the same memory, you'll struggle. David's picture and Carlo's talk both help, I hope.
They are very powerful in their limited way. Here's a sample of my code (no real secrets here):
union __ChannelsOn
{
BYTE Mask;
struct {
BYTE On1 : 1;
BYTE On2 : 1;
BYTE On3 : 1;
BYTE On4 : 1;
BYTE OnTOF : 1;
BYTE Unused : 1;
BYTE MasterOn : 1;
BYTE ScanOn : 1;
} Bits;
} ChannelsOn;
I have some hardware that has a command I send to it to turn channels on and off. I send a byte made up of flag bits. I could say:
__ChannelsOn c;
c.Mask = 1 << 3 | 1 << 7;
SendChannels (c);
or I say:
__ChannelsOn c;
c.Mask = 0;
c.Bits.On3 = 1;
c.Bits.ScanOn = 1;
SendChannels (c);
Both do the same thing - but which is more readable?
They are also used to make the variant structure, used to talk with COM/VB.
It's equivalent to:
struct VARIANT
{
int nType;
union {
int nInt;
long lLong;
DWORD dwDword;
BSTR bstr;
} Var;
};
I hope that helps a bit,
Iain.
In the process of moving to Sweden for love (awwww).
If you're in Scandinavia and want an MVP on the payroll (or happy with a remote worker), give me a job!
|
|
|
|
|
hi
what is the diffrence, if i write the interface declaration inside library in my .idl file . Are these two implementation serve the same purpose.
for Ex:
library XYZ
{
interface ABC
{
method 1 ;
}
[
uuid(________),
helpstring("_________")
]
coclass PQR
{
[default]interface ABC;
};
};
OR
interface ABC
{
method 1 ;
};
library XYZ
{
[
uuid(________),
helpstring("_________")
]
coclass PQR
{
[default] interface ABC ;
};
} ;
|
|
|
|
|
pandit84 wrote: Are these two implementation serve the same purpose.
Yes, since I interpret that as a question...
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|