Link to home
Start Free TrialLog in
Avatar of MikeP090797
MikeP090797

asked on

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

Avatar of NickRepin
NickRepin

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"}
};
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

Avatar of MikeP090797

ASKER

I am using Visual C++
let me check the solution
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.
Can you place any trace code (may be MessageBeep) inside MAGIC_BIND and ExtractFile to know which function is not called?
For which mode we have to find solution - for C++ or C?
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?
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.
About the mode, I don't relly care, can be either.
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"}
};



Nope, still no good.

Why do you write "LAA"? Don't you have only two parameters? Shouldn't it be "AA"? Return type may be something different.
Nope, still doesn't work
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.
ASKER CERTIFIED SOLUTION
Avatar of alexcohn
alexcohn
Flag of Israel image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Great!!!
Exactly what I needed