struct STRTEST
{
double s1;
STRTEST *pNext;
};
extern "C" __declspec(dllexport) int Test1(PDATA* pFirst)
{
PDATA *p=pFirst;
int a=0;
while(p->pNext!=NULL)
{
a++;
p->s1=a;
p=p->pNext;
}
return a;
}
//c#
[DllImport("test.dll", CharSet = CharSet.Unicode)]
public static extern int Test1( ref IntPtr ptr);
[StructLayout(LayoutKind.Sequential)]
public struct STRTEST
{
public double s1;
public IntPtr next;
}
public void test( int n )
{
STRTEST pFirst = new STRTEST();
STRTEST pCur=pFirst;
for(int i=0;i<n;i++)
{
if(i==0)
{
pCur.s1=i;
}
else
{
STRTEST pNext = new STRTEST();
pNext.s1=i;
IntPtr ptr = Marshal.AllocHGlobal(pNext);
Marshal.StructureToPtr(pNext, ptr, false);
pCur.next=ptr;
pCur = pNext;
}
}
IntPtr ptr1 = Marshal.AllocHGlobal(pFirst );
Marshal.StructureToPtr(pFirst , ptr1, false);
n= Test1(ref ptr1 )
}
调用test(10)后提示“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”
请高手帮忙解决
5 个解决方案
#1
用unsafe代码,C#里也用指针去读。哈哈很强大~
#2
....PDATA是啥?STRTEST*么?
那么既然已经是指针了为啥还要PDATA*?你的函数里根本就不分配内存返回吧?
从你的Test1在c#里的声明来看如果STRTEST*是PDATA的话那就是一个双重指针(STRTEST**).
这样的话你C函数本身就是错的.LZ先把指针理清楚再说吧.
另外C函数默认调用规则是cdecl,DllImport默认是StdCall,必须在DllImport里指明
那么既然已经是指针了为啥还要PDATA*?你的函数里根本就不分配内存返回吧?
从你的Test1在c#里的声明来看如果STRTEST*是PDATA的话那就是一个双重指针(STRTEST**).
这样的话你C函数本身就是错的.LZ先把指针理清楚再说吧.
另外C函数默认调用规则是cdecl,DllImport默认是StdCall,必须在DllImport里指明
#3
不好意思,extern "C" __declspec(dllexport) int Test1(PDATA* pFirst)
写错了,应该是 extern "C" __declspec(dllexport) int Test1(STRTEST* pFirst)
写错了,应该是 extern "C" __declspec(dllexport) int Test1(STRTEST* pFirst)
#4
那应该就是调用规则的问题了.
C默认的cdecl是调用方负责恢复栈指针ESP,
DllImport默认的是被调用方负责恢复栈指针ESP.
C默认的cdecl是调用方负责恢复栈指针ESP,
DllImport默认的是被调用方负责恢复栈指针ESP.
#5
extern "C" __declspec(dllexport) int Test1(STRTEST* pFirst)
{
STRTEST *p=pFirst;
int a=0;
while(p->pNext!=NULL)
{
a++;
p->s1=a;
p=p->pNext;
}
return a;
}
//STRTEST 为单向链表
{
STRTEST *p=pFirst;
int a=0;
while(p->pNext!=NULL)
{
a++;
p->s1=a;
p=p->pNext;
}
return a;
}
//STRTEST 为单向链表
#1
用unsafe代码,C#里也用指针去读。哈哈很强大~
#2
....PDATA是啥?STRTEST*么?
那么既然已经是指针了为啥还要PDATA*?你的函数里根本就不分配内存返回吧?
从你的Test1在c#里的声明来看如果STRTEST*是PDATA的话那就是一个双重指针(STRTEST**).
这样的话你C函数本身就是错的.LZ先把指针理清楚再说吧.
另外C函数默认调用规则是cdecl,DllImport默认是StdCall,必须在DllImport里指明
那么既然已经是指针了为啥还要PDATA*?你的函数里根本就不分配内存返回吧?
从你的Test1在c#里的声明来看如果STRTEST*是PDATA的话那就是一个双重指针(STRTEST**).
这样的话你C函数本身就是错的.LZ先把指针理清楚再说吧.
另外C函数默认调用规则是cdecl,DllImport默认是StdCall,必须在DllImport里指明
#3
不好意思,extern "C" __declspec(dllexport) int Test1(PDATA* pFirst)
写错了,应该是 extern "C" __declspec(dllexport) int Test1(STRTEST* pFirst)
写错了,应该是 extern "C" __declspec(dllexport) int Test1(STRTEST* pFirst)
#4
那应该就是调用规则的问题了.
C默认的cdecl是调用方负责恢复栈指针ESP,
DllImport默认的是被调用方负责恢复栈指针ESP.
C默认的cdecl是调用方负责恢复栈指针ESP,
DllImport默认的是被调用方负责恢复栈指针ESP.
#5
extern "C" __declspec(dllexport) int Test1(STRTEST* pFirst)
{
STRTEST *p=pFirst;
int a=0;
while(p->pNext!=NULL)
{
a++;
p->s1=a;
p=p->pNext;
}
return a;
}
//STRTEST 为单向链表
{
STRTEST *p=pFirst;
int a=0;
while(p->pNext!=NULL)
{
a++;
p->s1=a;
p=p->pNext;
}
return a;
}
//STRTEST 为单向链表