2

我在 C# 中使用 .Net 为 MapInfo Pro 构建了一个扩展。MapInfo 的旧版本是 32 位应用程序,最新版本是 64 位应用程序。我希望我的扩展程序能够与两者一起使用。虽然可以使用 .Net 调用 MapInfo 的许多功能,但其中一些仅适用于非托管 dll。其中一个 dll 称为 migrid.dll,我有 32 位和 64 位版本。但是我没有源代码,所以我无法获得该文件中函数的确切定义。

我想使用的函数之一是 GE_WriteContinuousValue。我拥有的关于该函数的唯一文档是如何使用 MapBasic(MapInfo 的默认编程语言)声明它:

声明函数 GE_WriteContinuousValue Lib "Migrid.dll" (

ByVal hGrid As Integer, '网格句柄

ByVal lCol As Integer, '列号

ByVal lRow As Integer, '行号

ByVal dValue As Float 'z 值

) 如果有错误,则为逻辑 'FALSE

'TRUE 成功

在我的 c# 代码中,我将此函数与 DllImport 一起使用:

[DllImport("migrid.dll", CallingConvention = CallingConvention.StdCall)]
public static extern bool GE_WriteContinuousValue(int hGrid, int lCol, int lRow, double dValue);

然后调用它,例如:

GE_WriteContinuousValue(iGridID, c, r, value);

使用 32 位 dll 可以正常工作。当我对 64 位 dll 使用相同的内容时,我在这一行得到“'System.AccessViolationException' Attempted to read or write protected memory”:

GE_WriteContinuousValue(iGridID, c, r, value);

同一个 dll 中的其他函数在 32 位和 64 位上都可以正常工作。所以它必须是特定于这个功能的东西。

希望有一种方法可以得到这个函数的确切定义,我在网上搜索了一个叫做雪人的工具。这给了我一些信息,但对我没有任何用处。也许它对你有帮助?

32 位 dll 的结果:

struct s43 {
signed char[4] pad4;
int32_t f4;
};

struct s44 {
signed char[4] pad4;
int32_t f4;
};

/* migridu.dll:222 */
int32_t migridu_dll_222 = 0x800000de;

void GE_WriteContinuousValue(int32_t a1, int32_t a2, int32_t a3) {
int32_t* edi4;
int32_t* esi5;
struct s43* edi6;
struct s44* esi7;

*edi4 = *esi5;
edi6->f4 = esi7->f4;
migridu_dll_222();
goto a2;
}

来自 64 位 dll 的结果:

void fun_180001b50() {
goto GE_WriteContinuousValue;
}

int64_t GE_WriteContinuousValue = 0x577c;

void GE_WriteContinuousValue() {
goto GE_WriteContinuousValue;
}

有人可以帮我摆脱 System.AccessViolationException 或为我指出正确的方向吗?

4

0 回答 0