• Welcome to Jose's Read Only Forum 2023.
 

Difference between a PB Type and a C++ struct?

Started by Heinz Grandjean, September 19, 2013, 11:27:37 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Heinz Grandjean

Yes, Frederick, you are right

I put the local instance in to overcome conflicts with "return"., I got because I'm learning.

Beside the "->",  I found another way:
(*newT).Var1. This does the job too.

And it demonstrates how simple and elegant our PB is ( hopefully not "was").

But now it's time to by a tutorial book to learn C++ systematical.

Thanks Frederick,
Heinz Grandjean




Frederick J. Harris

#16
Quote
But now it's time to by a tutorial book to learn C++ systematical.

That's a tough one.  To my way of thinking C++ is about 100 times more difficult than C.  I think there are a lot of folks who work with C that after a few years would feel fairly comfortable with saying, "I'm pretty much an expert at C".  But I'm not sure it works that way with C++.  I think a lot of folks who have worked with it for a lot of years would feel rather uncomfortable with proclaiming themselves to be "C++ experts".  At least the honest ones. 

In your example I was tempted to say you could specify the C++ export function as passing a reference to a MyStructType, that is MyStructType&, as opposed to a pointer to a MyStructType, that is, MyStructType*.  By doing that you could use the dot operator to return any of the struct members, rather than the '->'.  However, I'm thinking that would only work for C++ clients using the same development product, due to the fact without the extern_c C++ would mangle the function name, making it unrecognizable to a PowerBASIC client.  I could be wrong about that; I'd have to test it.  C syntax doesn't recognize the '&' symbol as a pass by reference mechanism.  C only knows passing pointers.    I guess one could say that's just another example of something C++ stole from basic syntax, along with string objects, etc., etc! :)

Heinz Grandjean

The reason going to MS C++ is the ability to have a visual designer.
But there is another baby called C#.
Am I right assuming the inoperability with PB because it is completely OOP?
Heinz Grandjean

Patrice Terrier

I found that when you have to pass structures between different languages, the easiest way is to use pointer, then ressort on the low level API MoveMemory to copy from one memory address to another.

Also memset could be handy to first clear the memory bloc you want to copy in.

The way memory was handled in C still works well with any language i know.

And when i write a DLL that will be used with PB or WinDev i am always using _stdcall to avoid the use of the cdecl close.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Heinz Grandjean

I fear, I' m not lucky( to inexperienced) using the  _stdcall...
BP declare:

DECLARE FUNCTION myTestFunction STDCALL LIB "D:\ESTWGJ_Quell\C++\Betrieb_DLL\Release\Betrieb_Dll.dll" ALIAS "Testfunction" (BYVAL MyNewType PTR,  BYVAL LONG PTR)  AS LONG   


C++ declare

__declspec(dllexport) long _stdcall Testfunction(MyNewStruct*, int*);


C++ Function


long __stdcall Testfunction (
          MyNewStruct* newT,
          int* count
          )
{

    long msg = 0;

switch (*count)
{
case 1:
      msg = (*newT).Var1;
      break;
case 2:
      msg = newT-> Var2;
      break;
case 3:
      msg = newT-> Var3;
      break;
};

return msg;
}


When I put the _stdcall  out and set in PB CDECL then it works.
With the _stdcall  in I get a "entry point not found" - message
Heinz Grandjean

Patrice Terrier

#20
This is because you are using 32-bit, then the function names are decorated, to solve this problem you have to use a .def file.

And you must setup your project properties like these:







And here is an example of the .def file i am using with WinLIFT32.def.

QuoteLIBRARY WinLIFT32.dll
EXPORTS
    skPopupOwner
    skCaptionFont
    skFont
    skFontBold
    skFontDlg
    skCaptionFontPlus
    skFontPlus
    skFontBoldPlus
    skFontDlgPlus
    skSkinDisable
    skSetZorder
    skGetHdcMemBmp
    skARGB
    ComputeAspect
    skChildOffset
    skSetLabelFont
    MinTrackSizeX
    MinTrackSizeY
    skVersion
    skInitEngine
    skSetAnchorCtrl
    skUsingDWM
    skSkinFolder
    skButImage
    skAuthor
    skBorder
    skSkinChildCtrl
    skSkinEnable
    skRedrawMenuBar
    skGetMenu
    skMenuContainer
    skSkinWindowUpdate
    skSkinWindow
    skCreateDW
    skDestroyDW
    skDialogAlert
    skDialogError
    skDialogInfo
    skDialogYesNo
    skDialogInput
    skButtonImage
    skPushButtonImage
    skSetToolTipText
    skGetToolTipText
    skCreateToolTip
    skRemoveToolTip
    skClockCtrl
    skComputeAngleFromPoint
    skGaugeSetMinMax
    skGaugeGetMinMax
    skGaugeSetPos
    skGaugeGetPos
    skKnobGauge
    skStaticImage
    skGetDWMregion
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Frederick J. Harris

If you had used the extern "C" in your C++ exported function, that should have prevented the C++ compiler from decorating/mangling the function name, which then makes it unrecognizable to other languages.

Patrice Terrier

#22
No, that doesn't work by me with 32-bit (VS2010), however it works in 64-bit (without using a .def file).

Here is how my extern functions are declared in the WinLIFT project:

Quote#include <windows.h>
//using namespace std;

#define C_IMPORT extern "C" __declspec(dllimport)
#define C_EXPORT extern "C" __declspec(dllexport)

const int ANCHOR_NONE                = 0;
const int ANCHOR_LEFT                = ANCHOR_NONE;
const int ANCHOR_WIDTH               = 1;
const int ANCHOR_RIGHT               = 2;
const int ANCHOR_CENTER_HORZ         = 3;
const int ANCHOR_HEIGHT              = 4;
const int ANCHOR_HEIGHT_WIDTH        = 5;
const int ANCHOR_HEIGHT_RIGHT        = 6;
const int ANCHOR_BOTTOM              = 7;
const int ANCHOR_BOTTOM_WIDTH        = 8;
const int ANCHOR_BOTTOM_RIGHT        = 9;
const int ANCHOR_CENTER_HORZ_BOTTOM  = 10;
const int ANCHOR_CENTER_VERT         = 11;
const int ANCHOR_CENTER_VERT_RIGHT   = 12;
const int ANCHOR_CENTER              = 13;

C_EXPORT HWND     skPopupOwner (IN HWND hWnd);
C_EXPORT HFONT    skCaptionFont ();
C_EXPORT HFONT    skFont ();
C_EXPORT HFONT    skFontBold ();
C_EXPORT HFONT    skFontDlg ();
C_EXPORT LONG_PTR skCaptionFontPlus ();
C_EXPORT LONG_PTR skFontPlus ();
C_EXPORT LONG_PTR skFontBoldPlus ();
C_EXPORT LONG_PTR skFontDlgPlus ();
C_EXPORT void     skSkinDisable (IN HWND hWnd);
C_EXPORT void     skSetZorder (IN HWND hWnd, IN HWND UseOrder);
C_EXPORT HDC      skGetHdcMemBmp (IN HWND hOwner);
C_EXPORT long     skARGB (IN BYTE A, IN BYTE R, IN BYTE G, IN BYTE B);
C_EXPORT void     ComputeAspect (IN long xPic, IN long yPic, IN long xCell, IN long yCell, OUT long &xP, OUT long &yP, OUT long &xS, OUT long &yS);
C_EXPORT void     skChildOffset (IN HWND hWnd, OUT long &ofX, OUT long &ofY);
C_EXPORT void     skSetLabelFont (IN HWND hCtrl, IN WCHAR* zFontName, IN WORD nFontSize, IN long ARGBcolor, IN WORD nFontStyle);
C_EXPORT long     MinTrackSizeX (IN long SizeX);
C_EXPORT long     MinTrackSizeY (IN long SizeY);
C_EXPORT WCHAR*   skVersion ();
C_EXPORT long     skInitEngine (IN WCHAR* zSkinFile, IN WCHAR* zUserKey);
C_EXPORT long     skSetAnchorCtrl (IN HWND hWnd, IN long AnchorMode);
C_EXPORT long     skUsingDWM ();
C_EXPORT WCHAR*   skSkinFolder ();
C_EXPORT HWND     skButImage (IN HWND hOwner, OUT HBITMAP hBitmap, IN long xLeft, IN long yLeft, IN long ButID);
C_EXPORT WCHAR*   skAuthor ();
C_EXPORT HWND     skBorder (IN HWND hWnd, IN long x, IN long y, IN long xW, IN long yH, IN long nID, IN long nBorder);
C_EXPORT void     skSkinChildCtrl (IN HWND hWnd, IN long RedrawFlag);
C_EXPORT void     skSkinEnable (IN HWND hWnd);
C_EXPORT void     skRedrawMenuBar(IN HWND hWnd);
C_EXPORT HMENU    skGetMenu (IN HWND hWnd);
C_EXPORT HWND     skMenuContainer (IN HWND hWnd);
C_EXPORT void     skSkinWindowUpdate (IN HWND hWnd, IN long RedrawFlag);
C_EXPORT long     skSkinWindow (IN HWND hWnd, WCHAR* zSysButTip);
C_EXPORT HWND     skCreateDW (IN HWND hParent);
C_EXPORT void     skDestroyDW (OUT HWND &hDW);
C_EXPORT long     skDialogAlert (IN WCHAR* zCaption, IN WCHAR* zMessage, IN WCHAR* zButton);
C_EXPORT long     skDialogError (IN WCHAR* zCaption, IN WCHAR* zMessage, IN WCHAR* zButton);
C_EXPORT long     skDialogInfo (IN WCHAR* zCaption, IN WCHAR* zMessage, IN WCHAR* zButton);
C_EXPORT long     skDialogYesNo (IN WCHAR* zCaption, IN WCHAR* zMessage, IN WCHAR* zButton);
C_EXPORT WCHAR*   skDialogInput (IN WCHAR* zCaption, IN WCHAR* zMessage, IN WCHAR* zButton);
C_EXPORT HWND     skButtonImage (IN HWND hOwner, IN WCHAR* zFullpathImageName, IN long x, IN long y, IN long ButID, IN long StateMax);
C_EXPORT HWND     skPushButtonImage (IN HWND hOwner, IN WCHAR* zFullpathImageName, IN WCHAR* zLabel, IN long x, IN long y, IN long xW, IN long yH, IN long ButID, IN long Alignment);
C_EXPORT void     skSetToolTipText (IN HWND hObj, IN WCHAR* zText);
C_EXPORT void     skGetToolTipText (IN HWND hObj, IN WCHAR* zLabel);
C_EXPORT HWND     skCreateToolTip (IN HWND hObj, IN WCHAR* zText);
C_EXPORT void     skRemoveToolTip (IN HWND hObj);
C_EXPORT HWND     skClockCtrl (IN HWND hOwner, IN WCHAR* zFullpathImageName, IN long x, IN long y, IN long w, IN long h, IN long nID, IN long ARGB1, IN long ARGB2, IN long GMT);
C_EXPORT long     skComputeAngleFromPoint(IN HWND hWnd, IN long mX, IN long mY);
C_EXPORT void     skGaugeSetMinMax (IN HWND hCtrl, IN long nMin, IN long nMax);
C_EXPORT void     skGaugeGetMinMax (IN HWND hCtrl, OUT long &nMin, OUT long &nMax);
C_EXPORT void     skGaugeSetPos (IN HWND hCtrl, IN long nPos, IN long RedrawFlag);
C_EXPORT long     skGaugeGetPos (IN HWND hCtrl);
C_EXPORT HWND     skKnobGauge (IN HWND hOwner, IN WCHAR* zFullpathImageName, IN long x, IN long y, IN long w, IN long h, IN long ButID, IN long MinValue, IN long MaxValue, IN long UsePos, IN long StateMax);
C_EXPORT HWND     skStaticImage (IN HWND hOwner, WCHAR* zFullpathImageName, IN long x, IN long y, IN long w, IN long h, IN long nID);
C_EXPORT HWND     skGetDWMregion (IN HWND hWnd);

Without using the .def file, the function name is always mangled by me in 32-bit mode using the __stdcall flag.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Heinz Grandjean

Thanks for all that information.

I have done  this (extern "C") ; it does not help...
I have set all the settings Patrice has shown, but I have Problems to set the *.def-file in the right place.
Am I right: It is not an include file with #Include?
Where can I find it in MS C++ Express?
How is it linked to the other files?
Trying to fill it as an include -file inside the Ide I get error-messages, starting with the key-word.

Heinz Grandjean

Feeling a little bit guilty of making such a rumor...
But maybe it is interesting for someone else??

Patrice Terrier

You can put the .def file inside of a folder that is within the Windows PATH.

On my computer i have added my folder D:\VS2010 into my path and all my .def files are in there.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Heinz Grandjean

Thank you, Patrice!
Could handle the global __stdcall(/Gz) entry and the *.def - file.
Now it does the job.
Interesting to see there is no longer need for these declares??


define C_EXPORT extern "C" __declspec(dllexport)
       C_EXPORT long Testfunction( MyNewStruct*, int* );
       C_EXPORT long Test2 (int*);

It works with or without them.

Heinz Grandjean

James C. Fuller

I use VC++ from the Win7 SDK and compile using batch files.

To get undecorated __stdcall in 32bit I use two calls.
the first compile/link creates a .def file which we use in a
the second call to add undecorated function names to the dll.
Where %F% is the file to compile and %VRES% is the RES file.

cl.exe  %F%.cpp %VRES% /EHsc /MT /link /DLL /OUT:"%F%.dll"
cl.exe /LD "%F%.obj" %VRES% "%F%.def"

James


Patrice Terrier

Heinz

QuoteInteresting to see there is no longer need for these declares??

You will need it, to create a 64-bit version from the same source code.

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com