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
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_
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_
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 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
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
ASKER
I am using Visual C++
let me check the solution
let me check the solution
ASKER
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?
Do you have any working dll for Magic like your one?
ASKER
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.
I don't have a working dll at the moment, but I'll try to get one.
ASKER
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"}
};
#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"}
};
ASKER
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.
ASKER
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.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Great!!!
Exactly what I needed
Exactly what I needed
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"}
};