2009-04-08 32 views
0

我保持通话从外部DLL以下时,得到一个AccessViolationException:AccessViolationException/Invoke的帮助

FILES_GetMemoryMapping(MapFile, out size, MapName, out PacketSize, pMapping, out PagePerSector); 

哪个有我设置为这样的原型:

[DllImport("Files.DLL", SetLastError = true)] 
    public static extern uint FILES_GetMemoryMapping(
     [MarshalAs(UnmanagedType.LPStr)] 
     string pPathFile, 
     out ushort Size, 
     [MarshalAs(UnmanagedType.LPStr)] 
     string MapName, 
     out ushort PacketSize, 
     IntPtr pMapping, 
     out byte PagesPerSector); 

现在,导致这种情况的参数很可能是第五个参数(IntPtr pMapping)。我将这段代码从C++应用程序移植到C#中。上面的第五个参数是一个指向结构的指针,该结构还包含指向另一个结构的指针。下面是我怎么有这些sctructs设置:

[StructLayout(LayoutKind.Sequential)] 
    public struct MappingSector 
    { 
     [MarshalAs(UnmanagedType.LPStr)] 
     public string Name; 
     public uint dwStartAddress; 
     public uint dwAliasedAddress; 
     public uint dwSectorIndex; 
     public uint dwSectorSize; 
     public byte bSectorType; 
     public bool UseForOperation; 
     public bool UseForErase; 
     public bool UseForUpload; 
     public bool UseForWriteProtect; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct Mapping 
    { 
     public byte nAlternate; 
     [MarshalAs(UnmanagedType.LPStr, SizeConst=260)] 
     public string Name; 
     public uint NbSectors; 
     public IntPtr pSectors; 
    } 

的C++等效的这些如下:

typedef struct { 
    char*  Name; 
    DWORD  dwStartAddress; 
    DWORD  dwAliasedAddress; 
    DWORD  dwSectorIndex; 
    DWORD  dwSectorSize; 
    BYTE  bSectorType; 
    BOOL  UseForOperation; 
    BOOL  UseForErase; 
    BOOL  UseForUpload; 
    BOOL  UseForWriteProtect; 
} MAPPINGSECTOR, *PMAPPINGSECTOR; 

typedef struct { 
    BYTE   nAlternate; 
    char   Name[MAX_PATH]; // MAX_PATH = 260 
    DWORD   NbSectors; 
    PMAPPINGSECTOR pSectors; 
} MAPPING, *PMAPPING; 

我有一种感觉,我做错了什么事有两种移植在这些结构,或移植了函数原型。一个麻烦的问题。

这个帖子顶部的函数在我的代码中被调用两次。一旦pMapping设置为null(这会将值放入“大小”中)。然后使用这个大小参数为内存分配一个新的结构体,并且现在使用指向这个分配的内存空间的指针进行pMapping的调用。 (pMapping也有一个指向另一个结构的指针,这个结构在这段时间也分配了一些空间)。

下面是完成这个旧的C++代码:

FILES_GetMemoryMapping((LPSTR)(LPCTSTR)MapFile, &Size, (LPSTR)MapName, &PacketSize, pMapping, &PagePerSector); 
// Allocate the mapping structure memory 
pMapping = (PMAPPING)malloc(sizeof(MAPPING)); 
pMapping->NbSectors = 0; 
pMapping->pSectors = (PMAPPINGSECTOR) malloc((Size) * sizeof(MAPPINGSECTOR)); 
printf("mapsectorsize: <%d>\n", football); 
printf("pMappingsize: <%d>\n", f2); 
// Get the mapping info 
FILES_GetMemoryMapping((LPSTR)(LPCTSTR)MapFile, &Size, (LPSTR)(LPCTSTR)MapName, &PacketSize, pMapping, &PagePerSector); 

我最初以为,所以我尝试了上述旧的C++代码,我不分配正确的空间量,并发现:

sizeof(MAPPING) = 272 
and 
sizeof(PMAPPINGSECTOR) = 40 

我做相同的检查在我的C#代码,发现如下:

Marshal.SizeOf(new Mapping()) = 16 
and 
Marshal.SizeOF(new MappingSector()) = 40 

我们在这里遇到了问题。 Mapping结构的大小应该是272,但只有16个。考虑到我可以做一个快速修复,我在这里手动分配了272而不是16,但它仍然出现了AccessViolationException错误。

关于如何解决这个问题的任何想法?或者还有什么可能会出错?

回答

1

“原型'不是正确的词,我喜欢“DLLImport声明”更好。

而我刚刚得到它的工作。

在C++

这样:

typedef struct { 
    BYTE      nAlternate; 
    char      Name[MAX_PATH]; // MAX_PATH = 260 
    DWORD      NbSectors; 
    PMAPPINGSECTOR  pSectors;  
} 

到C#:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] 
public struct Mapping 
{ 
    public byte nAlternate; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=260)] 
    public char[] Name; 
    public uint NbSectors; 
    public IntPtr pSectors; 
} 

字符数组不是字符串,而应被视为字符数组....谁会想到:P

0

我还没有完成所有这一切,恐怕,但如果你有'char *'的结构并且你把它们编组为'string',那么你应该小心用适当的CharSet = CharSet.Ansi属性装饰东西。

一件事是添加到您的帖子有用的是C++原型函数(我指的不是你的DllImport声明为“原型”,但是这可能只是我的。)

1

According to MSDN,你应该为一个固定长度的缓冲区传递一个StringBuilder。尝试以下或某些变体(未经测试):

[StructLayout(LayoutKind.Sequential)] 
public struct Mapping 
{ 
    public byte nAlternate; 
    [MarshalAs(UnmanagedType.LPStr, SizeConst=260)] 
    public StringBuilder Name; 
    public uint NbSectors; 
    public IntPtr pSectors; 

    public Mapping() 
    { 
     Name = new StringBuilder(259); 
     //This will be a buffer of size 260 (259 chars + '\0') 
    } 
} 
+0

我认为这与“结构不能包含显式无参数构造函数”限制相冲突...... – dlchambers 2011-07-08 21:01:24