我在 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 或为我指出正确的方向吗?