1,486
社区成员
发帖
与我相关
我的任务
分享
int32 s7_get_multiple_read_cnf(
void *od_ptr, /* In call */
ord16 *result_array, /* Returned */
ord16 *var_length_array, /* Call and Returned */
void *value_array /* Returned */
)
static void my_get_multiple_read_cnf(ord32 cp_descr)
{ int32 ret;
ord16 result[2],var_length[2];
ord8 data_buffer[4]; /* four Byte are necessary for reading two MWORD */
ord8 *value_ptr[2];
/* initialize arrays */
result[0] = S7_RESULT_OBJ_NOT_EXISTS;
result[1] = S7_RESULT_OBJ_NOT_EXISTS;
var_length[0] = 2;
var_length[1] = 2;
value_ptr[0] = &data_buffer[0]; /* set first pointer to begin of buffer */ /问题点
value_ptr[1] = &data_buffer[2]; /* set sec. pointer to offset 2 */ /问题点
if((ret=s7_get_multiple_read_cnf(NULL,result,var_length,value_ptr))!=S7_OK)
{
my_exit(cp_descr,"Error s7_get_multiple_read_cnf",ret);
}
}
Imports System.Runtime.InteropServices
Module Module1
<StructLayout(LayoutKind.Sequential)> _
Public Class ByteArray2
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> Public item() As Byte
Public Sub New()
ReDim Me.item(1)
End Sub
End Class
<StructLayout(LayoutKind.Sequential)> _
Public Class ByteArray8
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> Public item() As Byte
Public Sub New()
ReDim Me.item(7)
End Sub
End Class
<StructLayout(LayoutKind.Sequential)> _
Public Class IntArray2
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> Public item() As Integer
Public Sub New()
ReDim Me.item(1)
End Sub
End Class
Sub Main()
Dim value_buffer As New ByteArray2
Dim value_array As New IntArray2
Dim bytes As New ByteArray8
Console.WriteLine("value_buffer : Size = {0} : Count = {1}", Marshal.SizeOf(value_buffer), value_buffer.item.Count)
Console.WriteLine("value_array : Size = {0} : Count = {1}", Marshal.SizeOf(value_array), value_array.item.Count)
Console.WriteLine("bytes : Size = {0} : Count = {1}", Marshal.SizeOf(bytes), bytes.item.Count)
'申请一块内存pBuffer'
Dim pBuffer As IntPtr = Marshal.AllocHGlobal(2)
Debug.Assert(pBuffer.ToInt32 > 0, "地址不过2G.")
Console.WriteLine("pBuffer : {0:X8}", pBuffer.ToInt32)
'把value_array的指针执行前面的内存块'
For i = 0 To 1
value_array.item(i) = pBuffer.ToInt32 + i * 1
Next i
'把value_array复制到另外一块内存pArray'
Dim pArray As IntPtr = Marshal.AllocHGlobal(8)
Console.WriteLine("pArray : {0:X8}", pArray.ToInt32)
Marshal.StructureToPtr(value_array, pArray, True)
'查看pArray的内容'
Marshal.PtrToStructure(pArray, bytes)
Console.WriteLine(BitConverter.ToString(bytes.item))
'用pArray调用API'
'把返回的数据复制回数组'
Marshal.PtrToStructure(pBuffer, value_buffer)
Marshal.PtrToStructure(pArray, value_array)
Marshal.FreeHGlobal(pBuffer)
Marshal.FreeHGlobal(pArray)
Console.ReadLine()
End Sub
End Module
value_buffer : Size = 2 : Count = 2
value_array : Size = 8 : Count = 2
bytes : Size = 8 : Count = 8
pBuffer : 01364110
pArray : 01339F90
10-41-36-01-11-41-36-01
For i = 0 To read_para_index
var_length_array(i) = 1
GC = GCHandle.Alloc(value_buffer(i), GCHandleType.Pinned)
value_array(i) = GC.AddrOfPinnedObject.ToInt32
Next i
Imports System.Runtime.InteropServices
Module Module1
Sub Main()
Dim value_buffer(1) As Byte
Dim value_array(1) As Integer
Dim GC(1) As GCHandle
Dim bytes(24 - 1) As Byte
For i = 0 To 1
GC(i) = GCHandle.Alloc(value_buffer(i), GCHandleType.Pinned)
value_array(i) = GC(i).AddrOfPinnedObject.ToInt32
Console.WriteLine("{0:X8}", value_array(i))
Next i
'调用API'
For i = 0 To 1
GC(i).Free()
Next
Console.ReadLine()
End Sub
End Module
015BFB88
015CA18C
For i = 0 To read_para_index
var_length_array(i) = 1
GC = GCHandle.Alloc(value_buffer(i), GCHandleType.Pinned)
value_array(i) = GC.AddrOfPinnedObject.ToInt32
Next i
Tiger_Zhao你的办法可行~~~~
最后我将 value_array()定义成Integer类型后,DLL 中的函数执行正常,但是没有返回值,有个问题,我发现使用以上代码将value_buffer() 中对应的内存地址赋到 value_array() 中,并执行了DLL中的函数后, value_buffer() 的内存地址会变化(我通过VS中带的监视器监视我传给 value_array()的内存地址可以看到正确的返回值),所以导致在value_buffer() 中还是看不到返回值,请问有什么办法在这个脚本执行过程中使 value_buffer() 的内存地址不发生变化呢??