• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

My first steps with C++

Started by Patrice Terrier, July 30, 2010, 10:01:29 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Frederick J. Harris

#45
Hello Patrice!

       I'm sorry I missed your start of your C++ posts and endeavors!  All of July and a good bit of August I wasn't on the internet very much, as I was working hard at converting one of my eMbedded C++ projects over to Visual Studio C++ 2008.  Anyway, I didn't know the answer to your implicit linking question, as I had always done explicit linking.  However, regarding your questions about strings, years ago I started using my own string class I built myself.  I never fooled with C++'s string classes for various reasons.  I'll attach (pkzip file) a Visual Studio 2008 C++ project that exercises my string class some.  It uses Left, Right, Mid, InStr, Parse, etc.  Like you, I pretty much think in basic too.  You are certainly welcome to it if it would be of any help to you.  One of the reasons I use my own string class, other than that I like basic syntax, is that it doesn't add much to an executables size - only a couple k.  Microsoft has cleaned up their act quite a bit with string handling.  With Visual Studio 6 you had to include support for MFC to get their String class, and that added about 1M to an exes size, and for me that was much too high a price to pay.  Lately, things aren't so bad, but I still prefer my own class.  I've gotta say, I code in C++ just about the same as in PowerBASIC.  I really only use C++ classes for a few things.  Its worked pretty good for my string class and my ODBC wrapper class, and to tell the truth, that's about it.  I don't care for Windows Class Libraries at all.

Patrice Terrier

Ed,

Thank you for the ZIP file.

I have used the VS2010 string class, because it is very close to the C# and the WinDev syntax i know already.
In release mode, i can produce a code size that is almost the same than in PB, and that is what i wanted.

I avoid to use the C++ CRL, and stay as close as possible to pure C, using always __stdcall and char* for compatibility with my PBwin DLL.
And using of course only the flat API, to easily translate my code from one language to the other.

I have a question about your use of the const keyword before the parameters being passed to your procedures, do you use it as a BYVAL equivalent, or what?

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

Frederick J. Harris

The const keyword in C/C++ is very important.  If a parameter is declared as a const then any attempt to alter it in the procedure will be caught by the compiler.  I wouldn't say there is any relation ship to that and the PowerBASIC Byval override.

Where const really comes into its own in C++ is with reference parameters.  C didn't have reference parameters (had to pass pointers by value) but their addition to the C++ language was one of the major additions besides classes.  As you know, passing a reference in PowerBASIC or C++ is very advantaegous because no matter how large the object is, all that is really being pushed on the stack is a pointer - so its very fast.  The danger of passing a reference though in the case where you only want the data used - not modified, is that since the procedure has its address, it could be modified - bad if you don't want that.  So if you place the const keyword in front of a reference parameter you'll have the best of both worlds - fast parameter passing, and no chance of the data being inadvertantly modified.  I think you could say its a rather important C++ concept.


Patrice Terrier

#48
Ed

Thus, the const keyword is suitable for the case of pointer (when a parameter is passed by reference) that you don't want to change, ok.

Then it is like byval, but without pushing the value on the stack ;)

...




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

Frederick J. Harris

Quote
Then it is like byval, but without pushing the value on the stack

Yes, except I hate the comparison with byval because to me that implies a copying of data so that the function is working with a temporary copy the compiler created behind the scenes. 

I believe the only way you can create a similiar situation in PowerBASIC where you pass a reference to an object instead of a copy and the object can't be changed is if the object is an equate.  That's a bit limiting because you can't really modify an equate anywhere in a program once its been assigned.  Here's a little C++ program with output afterwards that shows that you can have a struct variable (Employee e1) that can be passed to two similiar functions - one as a const& and another where it can be modified...


#include <stdio.h>
#include <string.h>


struct Employee
{
unsigned iEmpNum;
unsigned iClassification;
double   dblSalary;
char     szName[64];
}; 


void SomeFunction1(const Employee& emp)
{
printf("In SomeFunction1 With const Employee Reference\n");
//emp.dblSalary=75000.01;        //unremark to produce compile error
}


void SomeFunction2(Employee& emp)
{
printf("In SomeFunction2 With Employee Reference\n");
emp.dblSalary=75000.01; 


 
int main(int argc, char *argv[])
{
Employee e1;

e1.dblSalary=60000.00,  e1.iClassification=2, e1.iEmpNum=2, strcpy(e1.szName,"John Doe");
SomeFunction1(e1);
SomeFunction2(e1);
getchar();

return 0;
}

//In SomeFunction1 With const Employee Reference
//In SomeFunction2 With Employee Reference



Interestingly, functions can be overloaded based on the const keyword.  To C++ two functions of the exact same name and parameter list differing only in the const keyword are two different functions.  Take a look at this...


#include <stdio.h>
#include <string.h>


struct Employee
{
unsigned iEmpNum;
unsigned iClassification;
double   dblSalary;
char     szName[64];
}; 


void SomeFunction(const Employee& emp)
{
printf("In SomeFunction With const Employee Reference\n");
//emp.dblSalary=75000.01;
}


void SomeFunction(Employee& emp)
{
printf("In SomeFunction With Employee Reference\n"); 
}

 
int main(int argc, char *argv[])
{
const Employee e1 = {1, 1, 75000.00, "Jim Smith"};
Employee e2;

e2.dblSalary=60000.00,  e2.iClassification=2, e2.iEmpNum=2, strcpy(e2.szName,"John Doe");
SomeFunction(e1); 
SomeFunction(e2);
getchar();

return 0;
}


//In SomeFunction With const Employee Reference
//In SomeFunction With Employee Reference



Patrice Terrier

The ZIP files attached to the posts of this thread have been updated, to fix the ZIP file corruption caused by the "Server Collapse".

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

James C. Fuller

Patrice,
  It just so happens I am working on a tutorial for Bc9(bcx) to illustrate calling a function in a dll which
in turn does a callback to the app, using a variaty of __cdecl and __stdcall functions.
I am showing this for both MinGW g++ 32/64 and VC++ 32/64.

As I mentioned in the other thread I uninstalled Visual Studio Express as it will only let you compile to 32bit without
a lot of hacking. You should not have a problem with one of the paid versions. I suggest not using the VS IDE.

I have only done this with the Win7.1 SDK on Win7 64. I don't know what Sdk Visual Studio installed on your machine.
Do you have this?
From Start menu -> All Programs -> Microsoft Windows SDK v7.1 -> Windows SDK 7.1 Command Prompt

If so we should be golden.

James






Patrice Terrier

#52
James

I already have SDK 7.0A, i shall follow your advice, and install SDK 7.1
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

James--

Spend all the afternoon to patch VS2010 to the latest, and installing SDK 7.1 that failed 3 times before i could figure from Google what to do (had to uninstall first the redistributable package that was installed by another software before i could succeed with SDK 7.1, a real pain).

Anyway now i should be up and running, and this story is another good reason why i want to go full SDK to avoid the need to install any redistributable runtime.

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

James C. Fuller

#54
Patrice,
  The main element for compiling from the command line is SetEnv.cmd located here on my Win7 64:
  C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd
A very interesting read. take a look when you get time.

The shortcut from the Start Button is:
C:\Windows\System32\cmd.exe /E:ON /V:ON /T:0E /K "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd"

When you select it you end up with the default -> 64 bit Debug mode.

You do NEED to spawn a new cmd processor as SetEnv.cmd needs the /V:ON which is usually off by default on most systems.
The /T:0E is for the yellow on black color and /E:ON is for command extensions which are on by default I believe.

I call it from a bat file so I can set it to anything I want.

So from a REGULAR command prompt (not the SDK 7.1) or a shell from your editor:

cmd.exe /V:ON /K VC.BAT <your file no extension cpp assumed> [X86 Or X64] [con gui dll] [Release Debug]

Example To compile MyTestDll_32.cpp to a 32bit dll Release build:
"cmd.exe /V:ON /K VC.BAT MyTestDll_32 X86 dll Release"

I just recently discovered how to do this from anta40 on hutch's Masm board.
He did not use any parameters for cl nor have I here. I'm sure you are knowledgeable enough to figure out what you might
want and add them.

My batch file.
First parameter is the source file name.
I always call it from the source directory but RadAsm3 adds the full path when calling so I strip off the
full path and use just the file name in the bat file -> SET F=%~n1
Also note it will automatically compile and link an rc file with the same name as the c++ source.
It will even search a res\ directory if you prefer to keep all your resources (icon's, pictures, ...) in another
folder.


@setlocal

@ECHO OFF

REM get just file name. RadAsm3 passes complete path with non project files
REM ----------------------------
SET F=%~n1
REM ----------------------------

IF NOT EXIST %F%.cpp GOTO usage

REM I have this set in RadAsm3 which calls this bat file.
REM unComment so we can find SetEnv.cmd
REM SET PATH=C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\;%PATH%


IF [%2]==[] GOTO usage
IF [%3]==[] GOTO usage
SET BUILD=%4
IF [%BUILD%]==[] SET BUILD=Release


REM Set up the environment for compiling.
REM parameter 2 -> X86 or X64
REM parameter 3 -> con or gui or dll
REM parameter 4 -> Release or Debug


CALL SetEnv.cmd /%2 /%BUILD%


IF /I [%3] == [CON] (
  SET SUBSYS= /SUBSYSTEM:CONSOLE
  SET FTYPE="a Windows Console App"
)

IF /I [%3] == [GUI] (
  SET SUBSYS=/SUBSYSTEM:WINDOWS
  SET FTYPE="a Windows Gui App"
)

IF /I [%3] == [DLL] (
  SET SUBSYS=/DLL
  SET FTYPE="a Windows DLL"
)


REM --------------------------------------------------------------
REM always use the %F%.rc file in the Res Directory if it exists
REM this should handle both projects and individual files with resources



IF EXIST res\%F%.rc (
  ECHO Compiling resources.....
  cd res
  Rc %F%
  SET VRES=res\%F%.res
  cd ..
) ELSE (
  IF EXIST %F%.rc (
    ECHO Compiling resources.....
    Rc %F%
    SET VRES=%F%.res
  )
)

REM --------------------------------------------------------------
ECHO Compiling "%F%.cpp" To %FTYPE%
REM Note: no compiler/linker parameters
REM---------------------------------------------------------------
IF /I [%3]==[DLL] (
cl.exe /D_USRDLL /D_WINDLL "%F%.cpp" %VRES% /link /DLL /OUT:"%F%.dll"
) ELSE (
cl.exe  %F%.cpp /Fe%F%.EXE %WIN_VER% %VRES% %SUBSYSTEM% %5 %6 %7 %8
)

ECHO Finished!
IF EXIST "%F%.obj" del "%F%.obj"
IF EXIST "%F%.res" del "%F%.res"
GOTO done
:usage
ECHO **************************************************************
ECHO  Usage:  VC.BAT MainFile  [x86  x64] [con  gui  dll] extra files
ECHO  Note:   ExtraFiles can be .libs, .res , .obj
ECHO **************************************************************
:done
endlocal
exit



I am only going to show one scenerio here. A c++ app calling a stdcall function in a dll where
the dll does a callback to the app (a cdecl function)

The attachment contains three other ones.

C++ App calling a cdecl function in a dll and the dll calls back to a cdecl function
C++ App Calling a stdcall function in a dll and the dll calls back to a stdcall function
C++ App Calling a cdecl function in a dll and the dll calls back to a stdcall function

My Bc9 code that produces and compiles the c++ code
Dll

'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
'vc_ccb_sdll_32.bas
'------------------------------------------------------------------------------
'MyDllFunction is a stdcall function that calls a cdecl function in the caller
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*

$DLL STDCALL
$CPP
$ONEXIT "cmd.exe /V:ON /K VC.BAT $FILE$ X86 dll Release"
  $TYPEDEF BOOL (*foo)(int,char*)
'==============================================================================
FUNCTION MyDllFunction(x$,fooptr as foo ) AS BOOL EXPORT
    DIM z$
    z$ = UCASE$(x$)
    IF fooptr(1, z$) = TRUE THEN
        MSGBOX "foo is true"
        FUNCTION = TRUE
    END IF
END FUNCTION
'==============================================================================


C++ Dll Code:

// *********************************************************************
// Created with Bc9 - BASIC To C/C++ Translator (V) 9.0.4.2 (2012/10/20)
//                 BCX (c) 1999 - 2009 by Kevin Diggins
// *********************************************************************
//              Translated for compiling with a C++ Compiler
//                           On MS Windows
// *********************************************************************
#include <windows.h>    // Win32 Header File
#include <windowsx.h>   // Win32 Header File
#include <commctrl.h>   // Win32 Header File
#include <commdlg.h>    // Win32 Header File
#include <mmsystem.h>   // Win32 Header File
#include <shellapi.h>   // Win32 Header File
#include <shlobj.h>     // Win32 Header File
#include <richedit.h>   // Win32 Header File
#include <wchar.h>      // Win32 Header File
#include <objbase.h>    // Win32 Header File
#include <ocidl.h>      // Win32 Header File
#include <winuser.h>    // Win32 Header File
#include <olectl.h>     // Win32 Header File
#include <oaidl.h>      // Win32 Header File
#include <ole2.h>       // Win32 Header File
#include <oleauto.h>    // Win32 Header File
#include <winsock.h>    // Win32 Header File
#include <process.h>    // dos
#include <conio.h>      // dos
#include <direct.h>     // dos
#include <io.h>         // dos
#include <ctype.h>      // dos/linux
#include <fcntl.h>      // dos/linux
#include <math.h>       // dos/linux
#include <stdio.h>      // dos/linux
#include <string.h>     // dos/linux
#include <stddef.h>     // dos/linux
#include <stdlib.h>     // dos/linux
#include <setjmp.h>     // dos/linux
#include <time.h>       // dos/linux
#include <stdarg.h>     // dos/linux
#include <sys/types.h> 
#include <sys/stat.h>   


// ***************************************************
// Compiler Defines
// ***************************************************

// C++
#if defined( __cplusplus )
  #define overloaded
  #define C_EXPORT EXTERN_C __declspec(dllexport)
  #define C_IMPORT EXTERN_C __declspec(dllimport)
#else
  #define C_EXPORT __declspec(dllexport)
  #define C_IMPORT __declspec(dllimport)
#endif

// Open Watcom defs
#if defined( __WATCOM_CPLUSPLUS__ ) || defined( __TINYC__ )
  #define atanl atan
  #define sinl  sin
  #define cosl  cos
  #define tanl  tan
  #define asinl asin
  #define acosl acos
  #define log10l log10
  #define logl   log
  #define _fcloseall fcloseall
#endif

// Borland C++ 5.5.1 defs - bcc32.exe
#if defined( __BCPLUSPLUS__ )
  // ===== Borland Libraries ==========
  #include <dos.h>
  #pragma comment(lib,"import32.lib")
  #pragma comment(lib,"cw32.lib")
  // ==================================
#endif

// Microsoft VC++
#ifndef DECLSPEC_UUID
  #if (_MSC_VER >= 1100) && defined ( __cplusplus )
    #define DECLSPEC_UUID(x)    __declspec(uuid(x))
  #else
    #define DECLSPEC_UUID(x)
  #endif
#endif

// *************************************************
// Tiny C support for LinkRes2Exe
#ifdef __TINYC__
  int dummy __attribute__ ((section(".rsrc")));
#endif
// *************************************************

#ifndef __cplusplus
  #error A C++ compiler is required
#endif
typedef BOOL (*foo)(int,char*);

// *************************************************
// Instruct Linker to Search Object/Import Libraries
// *************************************************
#if !defined( __LCC__ )
#pragma comment(lib,"kernel32.lib")
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"advapi32.lib")
#pragma comment(lib,"winspool.lib")
#pragma comment(lib,"shell32.lib")
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"oleaut32.lib")
#pragma comment(lib,"uuid.lib")
#pragma comment(lib,"odbc32.lib")
#pragma comment(lib,"odbccp32.lib")
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"comdlg32.lib")
#pragma comment(lib,"imagehlp.lib")
#pragma comment(lib,"version.lib")
#else
#pragma lib <winspool.lib>
#pragma lib <shell32.lib>
#pragma lib <ole32.lib>
#pragma lib <oleaut32.lib>
#pragma lib <uuid.lib>
#pragma lib <odbc32.lib>
#pragma lib <odbccp32.lib>
#pragma lib <winmm.lib>
#pragma lib <imagehlp.lib>
#pragma lib <version.lib>
#endif
// *************************************************
// End of Object/Import Libraries To Search
// *************************************************

// *************************************************
//        User's GLOBAL ENUM blocks
// *************************************************

// *************************************************
//            System Defined Constants
// *************************************************

#define cSizeOfDefaultString 2048

// *************************************************
//            User Defined Constants
// *************************************************


// *************************************************
//               Standard Prototypes
// *************************************************

char*   BCX_TmpStr(size_t,size_t= 128,int= 1);
char*   ucase (char*);
char*   _strupr_(char *);
char*   _strlwr_(char *);
// *************************************************
//          User Defined Types And Unions
// *************************************************


// *************************************************
//                System Variables
// *************************************************


// *************************************************
//            User Global Variables
// *************************************************

static PCHAR   *g_argv;
static int     g_argc;
static HINSTANCE BCX_hInstance;


// *************************************************
//               User Prototypes
// *************************************************

C_EXPORT BOOL __stdcall MyDllFunction (char*  ,foo);

// *************************************************
//            User Global Initialized Arrays
// *************************************************



// *************************************************
//                 Runtime Functions
// *************************************************

#ifndef BCXTmpStrSize
#define BCXTmpStrSize  2048
#endif
char *BCX_TmpStr (size_t Bites,size_t  iPad,int iAlloc)
{
  static int   StrCnt;
  static char *StrFunc[BCXTmpStrSize];
  StrCnt=(StrCnt + 1) & (BCXTmpStrSize-1);
  if(StrFunc[StrCnt]) {free (StrFunc[StrCnt]); StrFunc[StrCnt] = NULL;}
#if defined BCX_MAX_VAR_SIZE
  if(Bites*sizeof(char)>BCX_MAX_VAR_SIZE)
  {
  printf("Buffer Overflow caught in BCX_TmpStr - requested space of %d EXCEEDS %d\n",(int)(Bites*sizeof(char)),BCX_MAX_VAR_SIZE);
  abort();
  }
#endif
  if(iAlloc) StrFunc[StrCnt]=(char*)calloc(Bites+128,sizeof(char));
  return StrFunc[StrCnt];
}


char *ucase (char *S)
{
  register char *strtmp = BCX_TmpStr(strlen(S),128,1);
  return _strupr_(strcpy(strtmp,S));
}


char *_strupr_(char *string)
{
   char *s;

   if (string)
   {
      for(s = string; *s; ++s)
         *s = toupper(*s);
   }
   return string;
}

char *_strlwr_(char *string)
{
    char *s;

    if (string)
    {
       for (s = string; *s; ++s)
           *s = tolower(*s);
    }
    return string;
}



// ************************************
//       User Subs and Functions
// ************************************

C_EXPORT BOOL __stdcall MyDllFunction (char* x,foo  fooptr)
{
  static char    z[cSizeOfDefaultString];
  strcpy(z,ucase(x));
  if(fooptr(1,z)==true )
    {
      MessageBox (GetActiveWindow(),"foo is true","",0);
      return true;
    }
}


// *************************************************
//                  Main Program
// *************************************************


__declspec(dllexport) BOOL WINAPI DllMain (HINSTANCE hInst, DWORD Reason, LPVOID Reserved)
{
switch (Reason)
{
case DLL_PROCESS_ATTACH:
BCX_hInstance = hInst;
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}


Code to test the dll
Bc9:

'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
'vc_test_ccb_sdll_32.bas
' call a stdcall dll function  with a cdecl callback
'dll -> vc_ccb_sdll_32.dll
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*

$CPP
$ONEXIT "cmd.exe /V:ON /K VC.BAT $FILE$ X86 con Release vc_ccb_sdll_32.lib"

$TYPEDEF BOOL (*foo)(int,char*)

DECLARE FUNCTION MyDllFunction(A$,f As foo)AS BOOL

Dim rv As BOOL


rv = MyDllFunction ("little lamb", MyFoo)


PRINT "I'm Back and waiting"
PAUSE
'==============================================================================
'callback function called from ccb_sdll_32.dll
'------------------------------------------------------------------------------
FUNCTION MyFoo(a%, cc$) AS BOOL
    PRINT a%, " ", cc$
    FUNCTION = TRUE
END FUNCTION


C++

// *********************************************************************
// Created with Bc9 - BASIC To C/C++ Translator (V) 9.0.4.2 (2012/10/20)
//                 BCX (c) 1999 - 2009 by Kevin Diggins
// *********************************************************************
//              Translated for compiling with a C++ Compiler
//                           On MS Windows
// *********************************************************************
#include <windows.h>    // Win32 Header File
#include <windowsx.h>   // Win32 Header File
#include <commctrl.h>   // Win32 Header File
#include <commdlg.h>    // Win32 Header File
#include <mmsystem.h>   // Win32 Header File
#include <shellapi.h>   // Win32 Header File
#include <shlobj.h>     // Win32 Header File
#include <richedit.h>   // Win32 Header File
#include <wchar.h>      // Win32 Header File
#include <objbase.h>    // Win32 Header File
#include <ocidl.h>      // Win32 Header File
#include <winuser.h>    // Win32 Header File
#include <olectl.h>     // Win32 Header File
#include <oaidl.h>      // Win32 Header File
#include <ole2.h>       // Win32 Header File
#include <oleauto.h>    // Win32 Header File
#include <winsock.h>    // Win32 Header File
#include <process.h>    // dos
#include <conio.h>      // dos
#include <direct.h>     // dos
#include <io.h>         // dos
#include <ctype.h>      // dos/linux
#include <fcntl.h>      // dos/linux
#include <math.h>       // dos/linux
#include <stdio.h>      // dos/linux
#include <string.h>     // dos/linux
#include <stddef.h>     // dos/linux
#include <stdlib.h>     // dos/linux
#include <setjmp.h>     // dos/linux
#include <time.h>       // dos/linux
#include <stdarg.h>     // dos/linux
#include <sys/types.h> 
#include <sys/stat.h>   


// ***************************************************
// Compiler Defines
// ***************************************************

// C++
#if defined( __cplusplus )
  #define overloaded
  #define C_EXPORT EXTERN_C __declspec(dllexport)
  #define C_IMPORT EXTERN_C __declspec(dllimport)
#else
  #define C_EXPORT __declspec(dllexport)
  #define C_IMPORT __declspec(dllimport)
#endif

// Open Watcom defs
#if defined( __WATCOM_CPLUSPLUS__ ) || defined( __TINYC__ )
  #define atanl atan
  #define sinl  sin
  #define cosl  cos
  #define tanl  tan
  #define asinl asin
  #define acosl acos
  #define log10l log10
  #define logl   log
  #define _fcloseall fcloseall
#endif

// Borland C++ 5.5.1 defs - bcc32.exe
#if defined( __BCPLUSPLUS__ )
  // ===== Borland Libraries ==========
  #include <dos.h>
  #pragma comment(lib,"import32.lib")
  #pragma comment(lib,"cw32.lib")
  // ==================================
#endif

// Microsoft VC++
#ifndef DECLSPEC_UUID
  #if (_MSC_VER >= 1100) && defined ( __cplusplus )
    #define DECLSPEC_UUID(x)    __declspec(uuid(x))
  #else
    #define DECLSPEC_UUID(x)
  #endif
#endif

// *************************************************
// Tiny C support for LinkRes2Exe
#ifdef __TINYC__
  int dummy __attribute__ ((section(".rsrc")));
#endif
// *************************************************

#ifndef __cplusplus
  #error A C++ compiler is required
#endif
typedef BOOL (*foo)(int,char*);

// *************************************************
// Instruct Linker to Search Object/Import Libraries
// *************************************************
#if !defined( __LCC__ )
#pragma comment(lib,"kernel32.lib")
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"advapi32.lib")
#pragma comment(lib,"winspool.lib")
#pragma comment(lib,"shell32.lib")
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"oleaut32.lib")
#pragma comment(lib,"uuid.lib")
#pragma comment(lib,"odbc32.lib")
#pragma comment(lib,"odbccp32.lib")
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"comdlg32.lib")
#pragma comment(lib,"imagehlp.lib")
#pragma comment(lib,"version.lib")
#else
#pragma lib <winspool.lib>
#pragma lib <shell32.lib>
#pragma lib <ole32.lib>
#pragma lib <oleaut32.lib>
#pragma lib <uuid.lib>
#pragma lib <odbc32.lib>
#pragma lib <odbccp32.lib>
#pragma lib <winmm.lib>
#pragma lib <imagehlp.lib>
#pragma lib <version.lib>
#endif
// *************************************************
// End of Object/Import Libraries To Search
// *************************************************

// *************************************************
//        User's GLOBAL ENUM blocks
// *************************************************

// *************************************************
//            System Defined Constants
// *************************************************

#define cSizeOfDefaultString 2048

// *************************************************
//            User Defined Constants
// *************************************************


// *************************************************
//               Standard Prototypes
// *************************************************

void    Pause (void);
// *************************************************
//          User Defined Types And Unions
// *************************************************


// *************************************************
//            User Global Variables
// *************************************************

static PCHAR   *g_argv;
static int     g_argc;
static BOOL    rv;


// *************************************************
//               User Prototypes
// *************************************************

C_IMPORT BOOL   __stdcall MyDllFunction(char *,foo);
BOOL    MyFoo (int,char*);

// *************************************************
//            User Global Initialized Arrays
// *************************************************



// *************************************************
//                 Runtime Functions
// *************************************************

void Pause(void)
{
  printf("\n%s\n","Press any key to continue . . .");
  _getch();
}



// ************************************
//       User Subs and Functions
// ************************************

BOOL MyFoo (int a,char* cc)
{
  printf("% d%s%s\n",(int)a," ",cc);
  return true;
}


// *************************************************
//                  Main Program
// *************************************************

int main(int argc, char *argv[])
{
  g_argc = argc;
  g_argv = argv;
rv= MyDllFunction("little lamb", MyFoo);
printf("%s\n","I'm Back and waiting");
Pause();
  return 0;   /* End of main program */
}



James

Paul Squires

Quote from: Patrice Terrier on December 10, 2012, 06:55:11 PM
James--

Spend all the afternoon to patch VS2010 to the latest, and installing SDK 7.1 that failed 3 times before i could figure from Google what to do (had to uninstall first the redistributable package that was installed by another software before i could succeed with SDK 7.1, a real pain).

Anyway now i should be up and running, and this story is another good reason why i want to go full SDK to avoid the need to install any redistributable runtime.

...

Thanks Patrice! I tried to install 7.1 last week and ran into problems just like you did. I read your post today and then uninstalled the 2010 C++ redistributable packages. The SDK now installed perfectly.

:)

Paul Squires
FireFly Visual Designer SQLitening Database System JellyFish Pro Editor
http://www.planetsquires.com

Larry Charlton

fwiw VS 2012 Express, supports 64bit out of the box now.

Patrice Terrier

James,

Thank you for the ZIP file.

For now, i don't want to be biaised anymore with exotics, and want to use only Visual Studio, because it is defacto the standard.

So far i have been able to create my first C Win32 DLL, and i was able to call it from a short PB test.exe.

My next step would be to create a 64-bit DLL, and call it from WinDev  8)

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

James C. Fuller

Quote from: Patrice Terrier on December 11, 2012, 02:47:03 PM
James,

Thank you for the ZIP file.

For now, i don't want to be biaised anymore with exotics, and want to use only Visual Studio, because it is defacto the standard.

So far i have been able to create my first C Win32 DLL, and i was able to call it from a short PB test.exe.

My next step would be to create a 64-bit DLL, and call it from WinDev  8)

...

Patrice,
  I thought you wanted to create MFC free SDK code?

Any way I was able to create a batch file to do the same using VS 2012 Express and the Win8 SDK on Windows 8.
You may not need the Win8 SDK as it does not have any compilers but as Larry pointed out VS 2012 will create 64bit apps/dlls.

James


@setlocal

@ECHO OFF
:: -----------------------------------------------------------------
:: Batch file to compile c++ applications using Visual Studio 2012
:: and the Win8 sdk

REM get just file name. RadAsm3 passes complete path with non project files
REM ----------------------------
SET F=%~n1
REM ----------------------------

IF NOT EXIST %F%.cpp GOTO usage


IF [%2]==[] GOTO usage
IF [%3]==[] GOTO usage
REM SET BUILD=%4
REM IF [%BUILD%]==[] SET BUILD=Release


REM Set up the environment for compiling.
REM parameter 2 -> x86 or x86_amd64
REM parameter 3 -> con or gui or dll

CALL "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" %2

IF /I [%3] == [CON] (
  SET SUBSYS= /SUBSYSTEM:CONSOLE
  SET FTYPE="Windows Console App"
)

IF /I [%3] == [GUI] (
  SET SUBSYS=/SUBSYSTEM:WINDOWS
  SET FTYPE="Windows Gui App"
)

IF /I [%3] == [DLL] (
  SET SUBSYS=/DLL
  SET FTYPE="a Windows DLL"
)


REM --------------------------------------------------------------
REM always use the %F%.rc file in the Res Directory if it exists
REM this should handle both projects and individual files with resources



IF EXIST res\%F%.rc (
  ECHO Compiling resources.....
  cd res
  Rc %F%
  SET VRES=res\%F%.res
  cd ..
) ELSE (
  IF EXIST %F%.rc (
    ECHO Compiling resources.....
    Rc %F%
    SET VRES=%F%.res
  )
)

REM --------------------------------------------------------------
ECHO Compiling "%F%.cpp" To %FTYPE%
IF /I [%3]==[DLL] (
cl.exe /D_USRDLL /D_WINDLL "%F%.cpp" %VRES% /link /DLL /OUT:"%F%.dll"
) ELSE (
cl.exe  %F%.cpp /Fe%F%.EXE %WIN_VER% %VRES% %SUBSYSTEM% %5 %6 %7 %8
)

ECHO Finished!
IF EXIST "%F%.obj" del "%F%.obj"
IF EXIST "%F%.res" del "%F%.res"
GOTO done
:usage
ECHO **************************************************************
ECHO  Usage:  VC.BAT MainFile  [x86  x64] [con  gui  dll] extra files
ECHO  Note:   ExtraFiles can be .libs, .res , .obj
ECHO **************************************************************
:done
endlocal
exit




Patrice Terrier

James

I don't want to wrap my GDImage/WinLIFT API into Microsoft Foundation Class (MFC), for now i want to keep it as low level flat API (32/64-bit).

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