0

当我知道它是地址和参数时,我正在尝试调用一个函数。

但我不断崩溃:

在此处输入图像描述

现在我想知道我的代码是否正确,或者我没有源代码的主程序也不支持这样的调用?

这是我的代码:

///////////////////////////////////////////////////////
// From "amx.c", part of the PAWN language runtime:
// http://code.google.com/p/pawnscript/source/browse/trunk/amx/amx.c

ucell GetPlayerPosAddress = NULL;
cell GetPlayerPosPositionData[5] = {4*sizeof(cell),NULL,NULL,NULL,NULL};
AMX FakeAMX;

typedef cell AMX_NATIVE_CALL n_GetPlayerPos( AMX* amx, cell* params );
n_GetPlayerPos* func_GetPlayerPos = NULL;

int GetPlayerPos(int playerid,float *x,float *y,float *z)
{
    GetPlayerPosPositionData[1] = playerid;
    func_GetPlayerPos(&FakeAMX,GetPlayerPosPositionData);
    *x = GetPlayerPosPositionData[2];
    *y = GetPlayerPosPositionData[3];
    *z = GetPlayerPosPositionData[4];
    return 1;
}
///////////////////////////////////////////////////////
PLUGIN_EXPORT int PLUGIN_CALL AmxLoad( AMX *amx )
{
    //Code from sscanf2.5, [PAWN]SSCANF Author: Y_Less
    int
        num,
        idx;
    // Operate on the raw AMX file, don't use the amx_ functions to avoid issues
    // with the fact that we've not actually finished initialisation yet.  Based
    // VERY heavilly on code from "amx.c" in the PAWN runtime library.
    AMX_HEADER *
        hdr = (AMX_HEADER *)amx->base;
    AMX_FUNCSTUB *
        func;
    num = NUMENTRIES(hdr, natives, libraries);
    for (idx = 0; idx != num; ++idx)
    {
        func = GETENTRY(hdr, natives, idx);
        if (!strcmp("GetPlayerPos", GETENTRYNAME(hdr, func)))
        {
            GetPlayerPosAddress = func->address;
            FakeAMX.data = NULL;
            FakeAMX.base = (unsigned char*)&GetPlayerPosAddress;
            n_GetPlayerPos* func_GetPlayerPos = (n_GetPlayerPos*)GetPlayerPosAddress;
            std::cout << "GetPlayerPos Found!" << std::endl;
            break;
        }
    }
    //end sscanf cut
    return 1;
}

我想用这段代码实现的是我想调用一个 AMX 函数,但不是从 AMX 脚本调用,而是从这段代码所在的 DLL 调用。

您在我的代码中看到任何错误还是特定于 AMX 的东西?

我确实得到“找到 GetPlayerPos 地址!” 信息。

这就是我调用函数的方式:

            float X;            
            float Y;
            float Z;

            GetPlayerPos(playerid,&X,&Y,&Z);

这是定义和结构:

/* calling convention for native functions */
#if !defined AMX_NATIVE_CALL
  #define AMX_NATIVE_CALL
#endif
#if defined __GNUC__
  #define PACKED        __attribute__((packed))
#else
  #define PACKED
#endif

struct tagAMX;
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
                                   cell *result, cell *params);
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);

/* The AMX structure is the internal structure for many functions. Not all
 * fields are valid at all times; many fields are cached in local variables.
 */
typedef struct tagAMX {
  unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
  unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
  AMX_CALLBACK callback PACKED;
  AMX_DEBUG debug       PACKED; /* debug callback */
  /* for external functions a few registers must be accessible from the outside */
  cell cip              PACKED; /* instruction pointer: relative to base + amxhdr->cod */
  cell frm              PACKED; /* stack frame base: relative to base + amxhdr->dat */
  cell hea              PACKED; /* top of the heap: relative to base + amxhdr->dat */
  cell hlw              PACKED; /* bottom of the heap: relative to base + amxhdr->dat */
  cell stk              PACKED; /* stack pointer: relative to base + amxhdr->dat */
  cell stp              PACKED; /* top of the stack: relative to base + amxhdr->dat */
  int flags             PACKED; /* current status, see amx_Flags() */
  /* user data */
  long usertags[AMX_USERNUM] PACKED;
  void _FAR *userdata[AMX_USERNUM] PACKED;
  /* native functions can raise an error */
  int error             PACKED;
  /* passing parameters requires a "count" field */
  int paramcount;
  /* the sleep opcode needs to store the full AMX status */
  cell pri              PACKED;
  cell alt              PACKED;
  cell reset_stk        PACKED;
  cell reset_hea        PACKED;
  cell sysreq_d         PACKED; /* relocated address/value for the SYSREQ.D opcode */
  #if defined JIT
    /* support variables for the JIT */
    int reloc_size      PACKED; /* required temporary buffer for relocations */
    long code_size      PACKED; /* estimated memory footprint of the native code */
  #endif
} PACKED AMX;

/* The AMX_HEADER structure is both the memory format as the file format. The
 * structure is used internaly.
 */
typedef struct tagAMX_HEADER {
  int32_t size          PACKED; /* size of the "file" */
  uint16_t magic        PACKED; /* signature */
  char    file_version  PACKED; /* file format version */
  char    amx_version   PACKED; /* required version of the AMX */
  int16_t flags         PACKED;
  int16_t defsize       PACKED; /* size of a definition record */
  int32_t cod           PACKED; /* initial value of COD - code block */
  int32_t dat           PACKED; /* initial value of DAT - data block */
  int32_t hea           PACKED; /* initial value of HEA - start of the heap */
  int32_t stp           PACKED; /* initial value of STP - stack top */
  int32_t cip           PACKED; /* initial value of CIP - the instruction pointer */
  int32_t publics       PACKED; /* offset to the "public functions" table */
  int32_t natives       PACKED; /* offset to the "native functions" table */
  int32_t libraries     PACKED; /* offset to the table of libraries */
  int32_t pubvars       PACKED; /* the "public variables" table */
  int32_t tags          PACKED; /* the "public tagnames" table */
  int32_t nametable     PACKED; /* name table */
} PACKED AMX_HEADER;

#define USENAMETABLE(hdr) \
    ((hdr)->defsize==sizeof(AMX_FUNCSTUBNT))

#define NUMENTRIES(hdr,field,nextfield) \
    (unsigned)(((hdr)->nextfield - (hdr)->field) / (hdr)->defsize)

#define GETENTRY(hdr,table,index) \
    (AMX_FUNCSTUB *)((unsigned char*)(hdr) + (unsigned)(hdr)->table + (unsigned)index*(hdr)->defsize)

#define GETENTRYNAME(hdr,entry) \
    (USENAMETABLE(hdr) ? \
        (char *)((unsigned char*)(hdr) + (unsigned)((AMX_FUNCSTUBNT*)(entry))->nameofs) : \
        ((AMX_FUNCSTUB*)(entry))->name)

这就是程序中的函数“看起来像”的样子:

// native GetPlayerPos(playerid, &Float:x, &Float:y, &Float:z)
static cell AMX_NATIVE_CALL n_GetPlayerPos(AMX *amx, cell *params)
{
    CHECK_PARAMS(4);

        cell* cptr;
        amx_GetAddr(amx, params[2], &cptr);
        *cptr = amx_ftoc(pPlayer->m_vecPos.X);
        amx_GetAddr(amx, params[3], &cptr);
        *cptr = amx_ftoc(pPlayer->m_vecPos.Y);
        amx_GetAddr(amx, params[4], &cptr);
        *cptr = amx_ftoc(pPlayer->m_vecPos.Z);

        return 1;
}
4

1 回答 1

0

看起来func_GetPlayerPos函数指针为NULL。你有没有设置过?

于 2012-12-08T21:09:00.683 回答