confused with ::function statement - c++

I have see codes' example such as ::function() in VS C++ but I cannot uniderstand what does it means.
I understand that :: is used for accessing the member function from outside class, but I have seen examples where I do not find this case. For example in following code
// For painting in memory
class MemCanvas: public Canvas
{
public:
MemCanvas (HDC hdc)
: Canvas (::CreateCompatibleDC (hdc))
{}
~MemCanvas ()
{
::DeleteDC(_hdc);
}
};
See the ::CreateCompatibleDC() function !!
I understand that it is defined in the Windows.h but how it is defined here I cannot guess.

:: refers to the global namespace.
As a prefix for a function call it indicates that this is not a member function, it's a global namespace function.
Together with the naming convention for Windows API functions, it pretty much identifies a Windows API function as such. To the reader. Usually there's no naming conflict so it's not necessary for the compiler: it's just a device to communicate to a reader of the code.

Related

Syntax Type Name(Type) in function

I found in sample code strange syntax. I have no idea what this code does, but looks nothing.
What does syntax type Name(Type) in function means?
void doJob()
{
...
bool SetForward(bool); //strange line
...
}
It's a function declaration.
They don't have to be at file scope, but it's fairly rare to see them inside functions if you're not reading relatively ancient C code.
Function Declarations are usually done at the top of your program so that the main can access all of them !! However , what if you want your main not able to access that function ? You simply declare its prototype in the function which is going to use it !! Another Example can be seen a private function in a class which can only be accessed by class methods & not by the main program !!

C++ Access Violation while calling dll function

I am actually using an unmanaged C++ DLL, and I don't have access to the .h, .cpp or .lib, but only to the .DLL.
After using PE Explorer and finding the function I wanted to use, here is what I get :
#Tdtm_Dossier#Logon$qv; Index 1310; Unmangled Borland C++ Function: qualified function Tdtm_Dossier::Logon()
And here is what I get from using dumpbin :
1310 11F9 00105234 #Tdtm_Dossier#Logon$qv
Here is the exception :
Unhandled Exception at 0x034B258C (modDll.dll) in functionsCpp.exe : 0xC0000005 :
Access violation writting to 0x000000AC.
The code I am using to call and use this function is as follow :
#include <stdio.h>
#include <Windows.h>
#include <iostream>
typedef int (*Logon)();
int main()
{
HMODULE modDll;
int resultLogon;
modDll= LoadLibrary("C:\\dll\\modDll.dll");
Logon logon;
logon = (Logon)GetProcAddress(modDll,"#Tdtm_Dossier#Logon$qv");
if(logon)
{
resultLogon = logon(); //<-- This is where I get the exception
printf("Function has been loaded\n");
}
else
// TODO: Error message
FreeLibrary(modDll);
}
Since the DLL documentation doesn't give me any interesting information on how to use the function, I can't count on it.
The DLL is correctly loaded and the GetProcAddress does return something. I guess (but I'm not sure) that it has something to do with my typedef, but I can't figure out what could be the return type of this function.
If you read e.g. this document on Borland C++ name mangling you might figure out that the symbol name "#Tdtm_Dossier#Logon$qv" represents a non-static member function of the class Tdtm_Dossier. You can't call non-static member function like normal functions, they have a hidden first argument that becomes the this pointer in the member function.
What's happening here is probably that the Logon member function tries to access member variables of the object instance, of which there is none, which leads to undefined behavior and a crash.
To be able to use this library you need the header file and the link library. You can't just call functions (member or not) and hope for the best.

Writing a Delphi DLL linked in from C++ Application: Access to C++ Interface Member Functions creates Access Violation

I need to write a DLL (in Delphi 2009) that is to be linked into a third party application written in MS VC++. The concept is very much that of a plugin system, which means that the application runs perfectly well without the DLL, and loads it when it is present.
Upon certain events, the application calls functions that the DLL exports. Documentation has a list of defined functions, and the so called SDK provides some sample code, of course also in C++. I do not have access to the source code of the application itself.
Following is a somewhat lengthy introduction together with some code examples. The question (that will be asked again at the bottom of this post) is: How do I have to implement the applications C++ classes, passed as pointers to interfaces, in the Delphi DLL? I've already read a couple of threads on stackoverflow and other sources, but most of them deal with modifying both ends (C++ applicaton and Delphi DLL), which is not an option. So, what I'm looking for is someone who can assist in translating the C++ DLL code to Delphi DLL code.
The called functions typically receive some parameters (mostly TCHAR*, int and some ENUMs) and have a return value of type HRESULT. Some of them do also have a parameter that is described as a pointer to a "COM-like interface", intended to make it possible to call member functions defined inside the application. During translation, I have simply prepended the types with a 'T' and declared the correspondind types in a seperate unit (TCHAR* becomes PTCHAR and is defined as PTCHAR = PAnsiChar. That makes it easy to replace the types, should it prove necessary).
Currently, the DLL functions are already called by the application and the code in the DLL has full access to the "standard" parameters like Strings or Integers. Return values are passed back to the application, so reckon that the implementation of the export functions is correct. On of the shorter examples (that works in the Delphi implementation):
// C++ function defined in the SDK
DLLAPI int FPHOOK_OnStartFlowInstance(const TCHAR* strSvcAppName,
const TCHAR* strAppName,
const FLOW_SECTION_TYPE eSectionType,
IIFlowContext* pContext)
{
return 0;
}
// Delphi translation of the same function
function FPHOOK_OnStartFlowInstance( const strSvcAppName : PTCHAR;
const strAppName : PTCHAR;
const eSectionType : TFLOW_SECTION_TYPE;
pContext : PIIFlowContext) : Int; stdcall;
begin
dbg('ENTER FPHOOK_OnStartFlowInstance: strSvcAppName = ''%s'', strAppName = ''%s''',[String(strSvcAppName),String(strAppName)]);
result := 0;
end;
Now, the problem is that I need to call one of the member functions. Here is the definition of the class (C++) resp. the interface (Delphi). I've left out most of the functions just to save space, but will gladly provide more source code if helpful.
// (shortened) class definition from C++
class IIFlowContext : virtual public CIUnknown
{
// Operation
public:
virtual HRESULT getContextID(/*[out]*/unsigned short* pContextId) = 0;
virtual HRESULT cleanExecutionState() = 0;
/* skipped some other 'virtual HRESULT ...' */
};
// (shortened) interface declaration from Delphi
type IIFlowContext = Interface(IUnknown)
function getContextID(pContextId : Punsigned_short) : HRESULT; stdcall;
function cleanExecutionState : HRESULT; stdcall;
// skipped some other 'function ...'
end;
If I now try to access one of the member functions:
function FPHOOK_OnStartFlowInstance( ...,pContext : PIIFlowContext) : Int; stdcall;
var fphookResult : HRESULT;
begin
try
fphookResult := pContext.cleanExecutionState;
except On E: Exception do
dbg('FPHOOK_OnStartFlowInstance, pContext.cleanExecutionState: %s::%s',[E.ClassName,E.Message]);
end;
result := 0;
end;
an EAccessViolation error is caught by the except block and written to the debug log. I've already tried different conventions (not sure if 'convention' is the correct term here) like cdecl or safecall instead of stdcall, all with the same result.
This is where I currently have no clue at all where to look at... I've never been a C++ (or even C) programmer, so my translation to Delphi might well be wrong. Maybe there's some other point I'm missing.
Anyway, I'd be glad if someone with a little (or much) more experience would give me some hints.
Thanks in advance
Patrick
// 2010-11-05: What I extracted from the comments, the answers and the comments to the answers
Remko's suggestion to define the parameter as
var pContext : IIFlowContext;
gives almost the same outcome as my initial attempt as
pContext : PIIFlowContext;
The exception ist thrown in both cases, but the content of the variable is different. More information is given below where I've listed the different test cases.
Barry mentioned that Interfaces in Delphi (opposite to C++) already are pointers. While C++ therefore needs to pass a pointer to the class (aka pass as reference), Delphi already expects a reference to the class. The parameter should thus be declared as
pContext : IIFlowContext;
That is, not as a pointer to the interface, nor with a var modifier.
I ran the following three test cases, all of which had a debug break point at the very first instruction on the function exported by the dll:
1) declare the parameter as a pointer to the interface
pContext : PIIFlowContext;
Outcome: According to the debugger, pContext contains a pointer to memory address $EF83B8. Calling one of the interfaces methods leads to a jump to memory address $560004C2t and throws an EAccessViolation exception.
2) declare the parameter as a reference to the Interface
var pContext : IIFlowContext;
Outcome: The debugger shows the content of pContext as "Pointer($4592DC) as IIFlowContext". Calling the interfaces method leads to a jump to the same memory address $560004C2, which then throws the same execption.
3) declare the parameter as the Interface itself (without modifier)
pContext : IIFlowContext;
Outcome: The exported dll function does not even get called. An EAccessViolation is thrown (and caught by the debugger) before the jump into the dll function occurs.
From the above I conclude that it shouldn't be to much of a difference wether the parameter is declared as var pContext : IIFlowContext or pContext : PIIFlowContext, but it is a noticable difference if it's declared as pContext : IIFlowContext.
As requested, here's the output of the debuggers dissasembly view. In the comments I've noted the values of the registers after the execution of the operation to their left:
SystemHook.pas.180: fcnRslt := pContext.cleanExecutionState;
028A3065 8B4514 mov eax,[ebp+$14] // EAX now = $00EF83D0
028A3068 8B00 mov eax,[eax] // EAX now = $004592DC
028A306A 50 push eax
028A306B 8B00 mov eax,[eax] // EAX now = $0041DE86
028A306D FF5010 call dword ptr [eax+$10] // <-- Throws Exception, EAX+$10 contains $560004C2
028A3070 59 pop ecx
028A3071 8BD8 mov ebx,eax
The disassembly is exactly the same, no matter wether the parameter is a pointer to the interface or a var reference.
Is there anything else I should provide?
One additional question that came to my mind...
In the original header file from the SDK, the class is defined as
class IIFlowContext : virtual public CIUnknown
CIUnknown, in turn, is defined in another header file (win_unknown.h) as
class CIUnknown
{
// Operation
public:
virtual HRESULT QueryInterface(REFIID iid, void ** ppvObject) = 0;
virtual unsigned long AddRef(void) = 0;
virtual unsigned long Release(void) = 0;
static bool IsEqualIID(REFIID iid1, REFIID iid2)
{
if (memcmp(&iid1, &iid2, sizeof(IID)) == 0)
return true;
return false;
}
};
Is it OK to use IUnknown as base for the Delphi interfaces? I guess not, because as far as I know, IUnknown does not implement IsEqualIID and so there would be a shift in the VMT. But, how would I implement this in Delphi? Is C++ static the same as Delphi class function?
// 2010-11-18: Some Updates
Unfortunately, I've not yet found a way to get it working. One thing that indeed changed the behaviour was passing the interface reference as
const pContext : IIFlowContext;
As Barry stated, this inhibits delphi from "automagically" calling _AddRef() on the interface. This way, I was able to initiate and debug a call to member functions of the Interface. Now I can follow the execution quite some time and can even see some calls into the windows API (e.g. CriticalSections), but at some time it still throws an EAccessViolation Error.
Currently I have no further ideas. I think I will try to get hands on a MSVC++ compiler so that I can build the DLL like recommended by the SDK. If that works then maybe using C++ to create a wrapper around by Delphi code will be the solution.
Anyway, thanks a lot for your help so far! Any additional input will be very much appreciated, though.
Based on your most recent comment, I think I know what's going on; and I should have spotted it sooner.
IIFlowContext on the C++ side is a class; IIFlowContext* pContext is passing a pointer to the class, which is how COM-style interfaces are represented in C++.
But Delphi interfaces are already pointers; the indirection is assumed, as Delphi classes are never passed around by value, like C++ classes are. You should use IIFlowContext directly, no var or const modifier, in the Delphi entrypoint.
There may still be a problem with the interface method declaration; it'll be clearer with more info: see my latest comment to your question.
My translation would be:
function FPHOOK_OnStartFlowInstance( const strSvcAppName : TCHAR;
const strAppName : TCHAR;
const eSectionType : TFLOW_SECTION_TYPE;
var pContext : IIFlowContext) : Int; stdcall;
PS: how did you define TCHAR is it Ansi or Unicode/Wide ?

Can't use DLL (written in C++) in Delphi: The procedure entry point could not be located

I've compiled a DLL in Visual Studio (the source code is in C++, which I barely understand). Here's a piece of Scraper.h:
struct SWin
{
char title[512];
HWND hwnd;
};
SCRAPER_API bool ScraperGetWinList(SWin winList[100]);
Now I'm trying to use the above function in my Delphi application:
type
tWin = record
title: String;
hwnd: HWND;
end;
function ScraperGetWinList(var WinList: Array of tWin): Boolean; external 'Scraper.dll';
var
myWinList: Array [1..100] of tWin;
procedure TMainForm.GetWinListButtonClick(Sender: TObject);
begin
ScraperGetWinList(myWinList);
...
The project doesn't compile, and I get the following message: The procedure entry point ScraperGetWinList could not be located in the dynamic link library: Scraper.dll.
What am I doing wrong?
From my Linux experience, I'd say that you've encountered so-called "name-mangling" issue. The entry point of your procedure is not called "ScraperGetWinList", but something like "_ZN18ScraperGetWinListEpN4SWin".
The thing is that, Unlike in C, in C++ language the name of entry point is not the same as the function name. No wonder: assume, you have a set of overloaded functions; they should have different entry points in your DLL. That's where name mangling comes into play.
The most common solution to this problem is to define interface of your library in such a way that it will use C calling convention. No name mangling will happen with the interface functions then.
Note that you don't have to write the whole library in C, you only should declare functions for them to emit C-like entry points.
Usually it's written like this:
extern "C" {
SCRAPER_API bool ScraperGetWinList(SWin winList[100]);
// More functions
}
Recompile your library and use it in Delphi without problems.
Note, that you should also adjust calling conventions (stdcall or cdecl) for them to match in your C++ header and Delphi code. However, that's best explained in another question.
Name mangling is most likely the problem. Name mangling is usually done is C++ code,
and when writing a DLL in C++ that should be used by code in an other langauge,
you should use the Extern "C" construction as Pavel Shved already suggested.
When using DLLs, especially when writtin in other languages, you should also keep
an eye on calling conventions. I suggest that you specify in both delphi and c++ to use the stdcall calling convenstion. This is the calling convention also used by the windows api, so it guarantees the best interoperatability between different compilers.
This would mean
extern "C" {
SCRAPER_API __stdcall bool ScraperGetWinList(SWin winList[100]);
}
and
function ScraperGetWinList(var WinList: Array of tWin): Boolean; external 'Scraper.dll';
But that's not all, the stdcall calling convention has an impact on the name mangling, and it would turn out to be something like _ScraperGetWinList#4 (Where 4 is the size of the parameter, where an array would have a pointer to the first element, so 4 bytes)
To confirm the correct symbols to use, I suggest Dependency Walker
( http://www.dependencywalker.com/ ) this program shows that exactly the function names are exported by the dll. Having confirmed the name to be '_ScraperGetWinList#4' then you add this in delpgi like this:
function ScraperGetWinList(var WinList: Array of tWin): Boolean; external 'Scraper.dll' name '_ScraperGetWinList#4';
Have you actually exported the entry point function in the c++ code? This really stumped me the first time I compiled a C++ dll in Visual Studio for use in a dotnet app.
For example, I needed to expose a print driver in unmanaged code so some other developers could access it in VB.net. This is what I did.
In foo.cpp:
extern "c" {
___declspec(dllexport) bool FooBar()
{
// Call some code on my cpp objects to implement foobar
}
}
Then in a file called foo.def:
LIBRARY "mylib"
EXPORTS
FooBar
AnyOtherFunctionsItExports
This is how I got it to work. I might not be doing things the best possiable way. I am a little light on C++ experience and also mainly don't work on windows.

How do I call C++ functions from a Lua script?

I'm using Visual Studio 2005.
------------------------[ luapassing.cpp ]--------------------
#include "lua.h"
static int myCfunc (Lua_State *L){
double trouble = lua_tonumber(L,1);
lua_pushnumber(L,16.0 -trouble);
return 1;
}
int luaopen_luapassing (Lua_State *L){
static const lua_reg Map [] = {{"dothis",myCfunc},{NULL,NULL}};
luaL_register(L,"cstuff",Map);
return;
}
-------------------------[ csample.lua ]-------------------------
package.cpath = "./CLua2.dll"
require "luapassing"
print("hola")
print(seth.doThis(120))
I see several issues. I'll describe them, and provide a code fragment that should work as I believe you intended this sample to work.
Your first problem is that the C++ compiler mangled the name of the only function exported from your DLL whose name matters to Lua: luaopen_luapassing(). The stock binary distribution for Windows was compiled as a C program, and assumes a C style name for the DLL module entry point.
Also, you have the protocol for the luaopen_x function slightly wrong. The function returns an integer which tells Lua how many items on the top of Lua's stack are return values for use by Lua. The protocol assumed by require would prefer that you leave the new module's table object on the top of the stack and return it to Lua. To do this, the luaopen_x function would ordinarily use luaL_register() as you did, then return 1.
There is also the issue of naming. Modules written in pure Lua have the opportunity to be less aware of their names. But modules written in C have to export a function from the DLL that includes the module name in its name. They also have to provide that module name to luaL_register() so that the right table is created and updated in the global environment. Finally, the client Lua script will see the loaded module in a global table named like the name passed to require, which is also returned from require so that it may be cached in a local in that script.
A couple of other nits with the C code are that the numeric type really should be spelled lua_Number for portability, and that it would be conventional to use luaL_checknumber() rather than lua_tonumber() to enforce the required argument to the function. Personally, I would name the C implementation of a public function with a name related to its name that will be known publicly by Lua, but that is just a matter of taste.
This version of the C side should fix these issues:
#include "lua.h"
static int my_dothis (Lua_State *L){
lua_Number trouble = luaL_checknumber(L,1);
lua_pushnumber(L,16.0 -trouble);
return 1;
}
extern "C" int luaopen_luapassing (Lua_State *L){
static const lua_reg Map [] = {
{"dothis", my_dothis},
{NULL,NULL}
};
luaL_register(L,"luapassing",Map);
return 1;
}
The sample script then needs to refer to the loaded module by its proper name, and to the functions defined by that module by their proper names. Lua is case sensitive, so if the module creates a function named dothis(), then the script must use that same name, and cannot find it named doThis(), for example.
require "luapassing"
print("hola")
print(luapassing.dothis(120))
I should add that I haven't actually compiled and run the above, so there might be a typo or two left as an exercise ;-)
If you're going to be doing a lot of C++ to lua binding, you might want to take a look at luabind.
If you are compiling as C++ and want to match a 'C' interface, you should declare the externally visible functions as extern "C" to avoid name mangling.