|
Hello,
I am trying to compile this small dll function and am getting a linking error can someone help....Please....I am using Visual Studio 2008.
The error i get when i build is error LNK2019: unresolved external symbol _DetourTransactionBegin@0 referenced in function _DllMain@12
Here is the code.
Can someone help..Please
#include "stdafx.h"
#include "detours.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DetourTransactionBegin();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
DetourTransactionBegin();
break;
}
return TRUE;
}
thanks A Million.
|
|
|
|
|
Either add detours.cpp to your project (if you have it) or update your project settings to link to the library, perhaps named, detours.lib
|
|
|
|
|
Did you link to the appropriate library ? The one which defines the DetourTransactionBegin (possibly detour.lib ?)
|
|
|
|
|
yes under tools-> options -> vc++ directories i have both the directories..one under include and the other under lib....
|
|
|
|
|
That's not enough. You need to specify in your settings that you are linking with the library: "Project properties" -> "Linker" -> "Input" and in "Additional Dependencies" put the name of your library.
|
|
|
|
|
By the way, I prefer to set the include and lib directories in the project settings rather than in the options. The difference is that they will be specific to your project and not to visual studio. This has also the advantage that all the required information is contained in your project file that you can distribute with your sources.
|
|
|
|
|
same error message.....I have a project from someone with detours in it...and it compliled and did build fine with no errors or warnings..Thinking if its the way i started the new project..
|
|
|
|
|
Started a new project and once i add the detours.cpp i get this
1>------ Build started: Project: simpledll, Configuration: Debug Win32 ------
1>Compiling...
1>detours.cpp
1>e:\mydetour\simpledll\detours.cpp(22) : fatal error C1189: #error : Must define one of DETOURS_X86, DETOURS_X64, or DETOURS_IA64
1>Build log was saved at "file://e:\MyDetour\simpledll\Debug\BuildLog.htm"
1>simpledll - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
what did i miss....
If i remove the detours.cpp I get
1>------ Build started: Project: simpledll, Configuration: Debug Win32 ------
1>Compiling manifest to resources...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>Linking...
1>dllmain.obj : error LNK2019: unresolved external symbol _DetourTransactionBegin@0 referenced in function _DllMain@12
1>E:\MyDetour\simpledll\Debug\simpledll.dll : fatal error LNK1120: 1 unresolved externals
1>Build log was saved at "file://e:\MyDetour\simpledll\Debug\BuildLog.htm"
1>simpledll - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
|
|
|
|
|
By removing detours.cpp you remove the body of the function DetourTransactionBegin(..) and, though the project now compiles, the linker can't find it - the function body. But why remove detours.cpp in the first place?
Your first error is the one which you need to fix - and not by removing detours.cpp. You must define one of the possible values as the error message says. If you are not building for a 64 bit system it looks as if you need to add the code: #define DETOURS_X86 Though there may be slightly more to it...
|
|
|
|
|
I have tried everything I can possibly think of...Short of asking someone to actually complie it in a new project and tell me I am doing something wrong or is my setup of Visual studio thats the problem. If someone is willing to do that I am going to create a new project and write step by step instructions of what i pick and chose when making the project...could that be my problem?
I would really appreciate if someone tried to use this small detour function and be able to compile it using Visual Studio 2008.
PleasePlease..Help...
|
|
|
|
|
By all means try a new project, though I can't help out testing it I dont have VS available (long story).
Going back to the original #define error, did you try defining one of the values it asked for?
|
|
|
|
|
ok..i have a filling it's something to do with the project settings in visual Studio 2008.
Every search I have done for detours I get results with visual studio 2005.
I obviously had to use nmake to compile the detours. And a few changes in the _win32.cpp, I was able to compile the detours.
I created a new project, asked it to use the detours.lib and changed the setting to use precompiled headears. However doing that now i get an error
1>LINK : fatal error LNK1104: cannot open file '.\Debug\dllmain.obj'
I have a feeling I might have to get my hands on visual studio 2005.
Unless I have missed something...I am almost giving up on this.
|
|
|
|
|
Hey everybody,
Let's see if I have this code:
class R
{
public:
typedef void (*Method)();
Method onClick;
void Do()
{
(*onClick) ();
}
};
void ok()
{
printf("OK\r\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("main\n");
R r;
r.onClick = &ok;
r.Do();
...
Just runs. Function pointer works..
But if I try to point a NON-STATIC function of a class.. well cant do that! I need to pass class instance also.. But dunno if there's a way to do that without templates.
So any idea how to do that without using template?
To make it clear:
class A
{
public:
void run(void);
};
class R
{
public:
typedef void (*Method)();
Method onClick;
void Do()
{
(*onClick) ();
}
};
void ok()
{
printf("OK\r\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("main\n");
A a;
R r;
r.onClick = &a.run;
r.Do();
...
|
|
|
|
|
There is a difference between a regular function pointer as you have declared in R, and a "pointer to a member function," which is what you want in the last code example.
The syntax is quite cryptic, and I don't recall what it is, but if you search for "pointer to member function," I'm sure you'll come up with it.
|
|
|
|
|
A non-static method pointer is the same as any function pointer that needs parameters - you need to tell the caller what those parameters are.
So, you could do this:
class R
{
public:
typedef void (A::*Method)();
struct MethodCall { Method fn; A obj; };
MethodCall onClick;
void Do()
{
Method m = onClick.fn;
A& a = onClick.obj;
((a).*(m))();
}
};
int main(int argc, char* argv[])
{
A a;
R r;
r.onClick.obj = a;
r.onClick.fn = &A::run;
r.Do();
}
But then if you wanted to use ok as a handler as well, you'd need to add a separate data member for that.
Getting around all that is the raison d'etre for Boost.Function[^] (also in std::tr1::function in VC2008, I believe). With that (and a smidgen of Boost.Lambda[^]), I'd write your onClick handler like this:
#include <iostream>
#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
class A
{
public:
void run(void) { std::cout << "A::run\n"; }
};
class R
{
public:
boost::function<void()> onClick;
void Do()
{
onClick();
}
};
void ok()
{
std::cout << "ok\n";
}
int main(int argc, char* argv[])
{
A a;
R r;
r.onClick = ok;
r.Do();
using namespace boost::lambda;
r.onClick = bind(&A::run, var(a));
r.Do();
}
If you then want multiple handlers, Boost.Signals[^] is very useful as well!
[edit]It would be remiss of me not to point out that Boost.Function is compatible with the STL binders such as mem_fun[^] - but as Boost.Lambda is so much cooler, I hope you'll forgive me [/edit]
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
OK I forgot to mention the most important thing
I want to point my function at run time. I mean it should be any kind of function pointer which accept this. So this is not acceptable for me &A::run...
I do not need boost for that (this will do the job if I already knew the class):
class SomeClass;
typedef void (SomeClass::* SomeClassFunction)(void);
void Invoke(SomeClass *pClass, SomeClassFunction funcptr) {
(pClass->*funcptr)(); };
Seems like there's no way...
|
|
|
|
|
dehseth wrote: I do not need boost for that
Maybe not - but it sure makes things a lot easier And not just for function pointers!!
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
You don't like polymorphism, do you (i.e. why do you want to do that, cannot you find an OOP way to accomplish your needs)?
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]
|
|
|
|
|
Stuart,
Excellent answer, as usual. I have one question:
You gave the actual function call as:
((a).*(m))();
Why do we need the parenthesis around a ?
Why can we not write:
(a.*(m))(); ?
|
|
|
|
|
I can never remember the syntax you need for a member function pointer call - so I kept putting in brackets until it compiled I just happened to put the brackets round a before the ones that really mattered!!
[edit]
Richard Andrew x64 wrote: Excellent answer, as usual
PS - thank you for the compliment - I tries me best, Guvnor!
[/edit]
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
modified on Monday, March 2, 2009 4:11 PM
|
|
|
|
|
Very nicely written, Stuart. My 5 for you.
It is a crappy thing, but it's life -^ Carlo Pallini
|
|
|
|
|
There are three reasons you can't do this the way you think it should work:
First &a.run is not the right way of getting a pointer to a class function, it is &A::run.
Second you can't convert from your Method type above to &A::run.
Third you can't execute a non-static method of a class unless you have an instance of that class (and this looks quite normal because we have to know which instance it is whose method we want to execute, non-static method have no meaning without an instance)
This is how you would write it using your way of thinking:
class A{
public: void run(void);
};
class R{
public:
typedef void (A::*Method)();
Method onClick;
void Do(A* a)
{
(a->*onClick) ();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
printf("main\n");
A a;
R r;
r.onClick = &A::run;
r.Do(&a);...
}
As you can see however there is nothing much useful to generalize, so the above code is just hiding something for no apparent reason. But you needed an answer
You can't create a pointer for one class non-static method and use it as a pointer to another class method.
|
|
|
|
|
The reason this is so is that method does not know anything about the instance that calls it. The instance pointer (this) is resolved at the moment of method call. This:
C c;<br />
c.method();
is executed using always one and the same address of the method but the class instance pointer ( this-> ) is passed for example as the first hidden parameter (which is hidden from us) like this
method(&c)
or the instance pointer (&c) is moved into ECX register first and then method() is called where each this-> is then referred by the content of ECX.
You can't avoid this problem even with boost or any other library.
|
|
|
|
|
If you are ready to make a slight design change this is what you can do and to get something fairly useful
class T
{
public:
virtual void run() = 0;
virtual void run1() = 0;
};
class A : public T
{
public:
void run(){
};
void run1(){
};
};
class F : public T
{
public:
void run(){
};
void run1(){
};
};
class R{
public:
typedef void (T::*Method)();
Method onClick;
void Do(T* t)
{
(t->*onClick)();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
F f;
R r;
r.onClick = &T::run;
r.Do(&a);
r.Do(&f);
r.onClick = &T::run1;
r.Do(&a);
r.Do(&f);
...
modified on Monday, March 2, 2009 5:57 PM
|
|
|
|
|