Any knows Magic?

I need to develop a DLL to be used with Magic (I hope somebody heard about it, it's a database development tool). I got an example on how it should be done, but when I tried to run it, it didn't work. It says 'User procedure/function could not be found/loaded.
 If somebody has done it before, please see what's wrong with this code, its probobly something obvious:


----------
ExtrPkg.C
----------

//#include "..\general.h"
#include "magic.h"
#include <windows.h>


#define FUNC_CNT     1

void    cdecl main (void);

long *ExtractFile(char *szPkg, char *szTitle);

//Definition of the dll procedures
static FUNC_DSC fdsc_tbl[FUNC_CNT] =
      {
      {"ExtractFile", ExtractFile, 2, "LAA"}
      };
      


//module definition
static EXT_MODULE ext_module = {0, NULL, NULL, FUNC_CNT, fdsc_tbl, (Uchar*)"ExtrPkg"};

//module definition callback  
void*
MAGIC_BIND(void)
{
   return (&ext_module);
}

//Dll Entry Point
BOOL
WINAPI DllMain (HINSTANCE hInst, DWORD ulReason, LPVOID lpReserved)
{
   return (1);
}



//--------------------
//Main procedure
long *
ExtractFile(char *szPkg, char *szTitle)
{
      static long i=1;
      return (&i);
}

---------
Magic.h
---------
#ifndef USERPROC_USER_H
 #define USERPROC_USER_H
 #define DRIVER_LABEL_SIZE          8
 #define NULL_PTR                   ((void far *) 0)
 #define USER_FAR                  
 #define USERPROC_MAX_PARM          30

 typedef
    unsigned char  Uchar;
 typedef
    unsigned short Ushort;
typedef
   unsigned long Ulong;
#endif

#define MIN(a,b)                    (((a) < (b)) ? (a) : (b))

#define MODULE_LABEL_LEN            DRIVER_LABEL_SIZE
#define FUNC_NAME_LEN               20

#define USERPROC_ALPHA              'A'   /* parameter is string           */
#define USERPROC_BLOB               'B'   /* parameter is blob             */
#define USERPROC_LONG               'L'   /* --/--/--/-- pointer to long   */
#define USERPROC_DOUBLE             'D'   /* --/--/--/-- pointer to double */

#define USERPROC_DELIM              '.'   /* "module.func_name" delimiter */

#define DRIVER_TYPE_USERPROC        'U'

/*------------------------------------------------------------------------*/
/* Tipes                                                                  */
/*------------------------------------------------------------------------*/
typedef     /* structure used internally for communication */
   struct
   {
      void USER_FAR *next_ext_item;
      Ushort         sign;                     /* must be EXT_SIGNATURE */
      Ushort         psp_seg;
      Ushort         driver_type;               /* DRIVER_TYPE_USERPROC */
      Uchar          driver_label[DRIVER_LABEL_SIZE];
      void USER_FAR *driver_info;
      Ushort         use_cnt;
   } EXT_ITEM;

typedef     /* structure defining module function */
   struct
   {
       Uchar USER_FAR *func_name;  /* name (label) of a function */
       void  USER_FAR *func_addr;  /* pointer to function        */
       Ushort          arg_cnt;    /* number of arguments        */
       Uchar USER_FAR *arg_attrs;  /* string of attributes 'A','L','D' */
   }  FUNC_DSC;

typedef     /* structure defining module */
   struct
   {
      Ushort             use_cnt;         /* only for Magic use            */
      void     USER_FAR *ini_func_addr;   /* called upon initialization    */
      void     USER_FAR *trm_func_addr;   /* called upon termination       */
      Ushort             func_cnt;        /* number of functions in module */
      FUNC_DSC USER_FAR *func_dsc_tbl;    /* function table                */
      Uchar    USER_FAR *module_name;     /* name (label) of module        */
      Ushort             context_hdl;
   } EXT_MODULE;

/*-----------------------------------------------------------------------*/
/* Functions                                                             */
/*-----------------------------------------------------------------------*/
void cdecl userproc_ext (EXT_MODULE *ext_module, Ulong mem_required);


-------------
ExtrPkg.def
-------------
LIBRARY ExtrPkg
DESCRIPTION 'ExtrPkg'
HEAPSIZE   1024

EXPORTS
 
 MAGIC_BIND @1
 ExtractFile @2

I need to develop a DLL to be used with Magic (I hope somebody heard about it, it's a database development tool). I got an example on how it should be done, but when I tried to run it, it didn't work. It says 'User procedure/function could not be found/loaded.
 If somebody has done it before, please see what's wrong with this code, its probobly something obvious:


----------
ExtrPkg.C
----------

//#include "..\general.h"
#include "magic.h"
#include <windows.h>


#define FUNC_CNT     1

void    cdecl main (void);

long *ExtractFile(char *szPkg, char *szTitle);

//Definition of the dll procedures
static FUNC_DSC fdsc_tbl[FUNC_CNT] =
      {
      {"ExtractFile", ExtractFile, 2, "LAA"}
      };
      


//module definition
static EXT_MODULE ext_module = {0, NULL, NULL, FUNC_CNT, fdsc_tbl, (Uchar*)"ExtrPkg"};

//module definition callback  
void*
MAGIC_BIND(void)
{
   return (&ext_module);
}

//Dll Entry Point
BOOL
WINAPI DllMain (HINSTANCE hInst, DWORD ulReason, LPVOID lpReserved)
{
   return (1);
}



//--------------------
//Main procedure
long *
ExtractFile(char *szPkg, char *szTitle)
{
      static long i=1;
      return (&i);
}

---------
Magic.h
---------
#ifndef USERPROC_USER_H
 #define USERPROC_USER_H
 #define DRIVER_LABEL_SIZE          8
 #define NULL_PTR                   ((void far *) 0)
 #define USER_FAR                  
 #define USERPROC_MAX_PARM          30

 typedef
    unsigned char  Uchar;
 typedef
    unsigned short Ushort;
typedef
   unsigned long Ulong;
#endif

#define MIN(a,b)                    (((a) < (b)) ? (a) : (b))

#define MODULE_LABEL_LEN            DRIVER_LABEL_SIZE
#define FUNC_NAME_LEN               20

#define USERPROC_ALPHA              'A'   /* parameter is string           */
#define USERPROC_BLOB               'B'   /* parameter is blob             */
#define USERPROC_LONG               'L'   /* --/--/--/-- pointer to long   */
#define USERPROC_DOUBLE             'D'   /* --/--/--/-- pointer to double */

#define USERPROC_DELIM              '.'   /* "module.func_name" delimiter */

#define DRIVER_TYPE_USERPROC        'U'

/*------------------------------------------------------------------------*/
/* Tipes                                                                  */
/*------------------------------------------------------------------------*/
typedef     /* structure used internally for communication */
   struct
   {
      void USER_FAR *next_ext_item;
      Ushort         sign;                     /* must be EXT_SIGNATURE */
      Ushort         psp_seg;
      Ushort         driver_type;               /* DRIVER_TYPE_USERPROC */
      Uchar          driver_label[DRIVER_LABEL_SIZE];
      void USER_FAR *driver_info;
      Ushort         use_cnt;
   } EXT_ITEM;

typedef     /* structure defining module function */
   struct
   {
       Uchar USER_FAR *func_name;  /* name (label) of a function */
       void  USER_FAR *func_addr;  /* pointer to function        */
       Ushort          arg_cnt;    /* number of arguments        */
       Uchar USER_FAR *arg_attrs;  /* string of attributes 'A','L','D' */
   }  FUNC_DSC;

typedef     /* structure defining module */
   struct
   {
      Ushort             use_cnt;         /* only for Magic use            */
      void     USER_FAR *ini_func_addr;   /* called upon initialization    */
      void     USER_FAR *trm_func_addr;   /* called upon termination       */
      Ushort             func_cnt;        /* number of functions in module */
      FUNC_DSC USER_FAR *func_dsc_tbl;    /* function table                */
      Uchar    USER_FAR *module_name;     /* name (label) of module        */
      Ushort             context_hdl;
   } EXT_MODULE;

/*-----------------------------------------------------------------------*/
/* Functions                                                             */
/*-----------------------------------------------------------------------*/
void cdecl userproc_ext (EXT_MODULE *ext_module, Ulong mem_required);


-------------
ExtrPkg.def
-------------
LIBRARY ExtrPkg
DESCRIPTION 'ExtrPkg'
HEAPSIZE   1024

EXPORTS
 
 MAGIC_BIND @1
 ExtractFile @2

LVL 8
MikeP090797Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

NickRepinCommented:
It seems that Magic loads functions from your dll by GetProcAddress().

If you compile your dll in C++ mode, you have to declare all of your exported (external) functions as extern "C" :

extern "C" long *ExtractFile(char *szPkg, char *szTitle);

extern "C" void* MAGIC_BIND...

Also, both in C and C++ mode, you have to specify that the names of all your functions has additional underscore:

static FUNC_DSC fdsc_tbl[FUNC_CNT] =
{
      {"_ExtractFile", ExtractFile, 2, "LAA"}
};
0
NickRepinCommented:
I just checked it again...
Microsoft linker removes underscore from the function name, so "ExtractFile" is ok.

What compiler do you use?

If Borland, then use -u- command-line option, OR specify in the .def file:

EXPORTS
 MAGIC_BIND=_MAGIC_BIND @1
 ExtractFile=_ExtractFile @2

0
MikeP090797Author Commented:
I am using Visual C++
let me check the solution
0
Introduction to Web Design

Develop a strong foundation and understanding of web design by learning HTML, CSS, and additional tools to help you develop your own website.

MikeP090797Author Commented:
I tried adding extern "C" for the .cpp file, and also tried compiling it as .C file. It didn't work. However, Dependency viewer shows the exports correctly.
0
NickRepinCommented:
Can you place any trace code (may be MessageBeep) inside MAGIC_BIND and ExtractFile to know which function is not called?
0
NickRepinCommented:
For which mode we have to find solution - for C++ or C?
0
NickRepinCommented:
Also try to find "MAGIC_BIND" string inside Magic executables (exe, dll - use text viewer) and check its exact spelling.

Do you have any working dll for Magic like your one?
0
MikeP090797Author Commented:
Tried that. MAGIC_BIND is called, ExtractFile not.

I don't have a working dll at the moment, but I'll try to get one.
0
MikeP090797Author Commented:
About the mode, I don't relly care, can be either.
0
NickRepinCommented:
What is this:

#define USERPROC_DELIM              '.'   /* "module.func_name" delimiter */


May be, you have to use

static FUNC_DSC fdsc_tbl[FUNC_CNT] =
{
      {"ExtrPkg.ExtractFile", ExtractFile, 2, "LAA"}
};



0
MikeP090797Author Commented:
Nope, still no good.

0
alexcohnCommented:
Why do you write "LAA"? Don't you have only two parameters? Shouldn't it be "AA"? Return type may be something different.
0
MikeP090797Author Commented:
Nope, still doesn't work
0
alexcohnCommented:
see http://www.geocities.com/SiliconValley/Bit/1809/ for an example of a Magic extension DLL that works. Ask the author http://www.geocities.com/SiliconValley/Bit/1809/contact.htm how he does this.

But it's possible that the problem is that simply your DLL cannot load for a whatever reason - e.g. some DLL it is linked to is missing. In that case the problem is not the UDF declaration you must fix.
0
alexcohnCommented:
Look at http://ourworld.compuserve.com/homepages/craig_martin/mgdelphi.zip

You will learn that:
1. You must write  {"ExtractFile", ExtractFile, 2, "AAL"}
2. You must have 1-byte alignment defined for compiler
3. You must write long * WINAPI ExtractFile(char *szPkg, char *szTitle)
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MikeP090797Author Commented:
Great!!!
Exactly what I needed
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.