1:在DBOP_API.dll中,定义了如下的结构体和API#pragma pack(1)
struct DBOP_SNAPSHOT_TAG_VAL //描述标签点值的相关信息的结构
{
TAG_ID tagID; /* 标签点的唯一ID */
TIMESTAMP timeStamp; /* 秒级时间戳 */
unsigned short ms; /* 毫秒 */
unsigned char tagType; /*该标签点的值类型 */
unsigned char quality; /* 数据质量 */
unsigned char val[1]; /* 当前值,根据标签点数据类型的不同长度不一 ,变化范围1----128 ,这里用到了越界*/
};DBOP_API int DBOP_SetSnapshotValue ( IN TAG_ID tagID, IN struct DBOP_SNAPSHOT_TAG_VAL* pVal);
DBOP_API int DBOP_GetSnapshotValue ( IN TAG_ID tagID, OUT struct DBOP_SNAPSHOT_TAG_VAL* pVal, IN int bufLen);
2:现在需要在c#下面调用:[DllImport("dbop_dll.dll", EntryPoint = "DBOP_SetSnapshotValue", CharSet = CharSet.Ansi)]
public static extern int DBOP_SetSnapshotValue( uint tagID, APICommonDataStruct.DBOP_SNAPSHOT_TAG_VAL pVal);
[DllImport("dbop_dll.dll", EntryPoint = "DBOP_GetSnapshotValue", CharSet = CharSet.Ansi)]
public static extern int DBOP_GetSnapshotValue(uint tagID, ref DBOP_SNAPSHOT_TAG_VAL pVal, int bufLen); public struct DBOP_SNAPSHOT_TAG_VAL //描述标签点值的相关信息的结构
{
public uint tagID; /* 标签点的唯一ID */
public uint timeStamp; /* 秒级时间戳 */
public ushort ms; /* 毫秒 */
public byte tagType; /*该标签点的值类型 */
//[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)]
public byte quality; /* 数据质量 */
[MarshalAs(UnmanagedType.ByValArray, SizeConst =128)]
public byte [] val; /* 该标签点的值的第一个字节 */
};
其中最后一个字节数组取的前面变长结构体的最大长度3 现在的问题是我可以读取数据,但是无法将数据写入!希望各位知道的指教啊,感激不尽!
struct DBOP_SNAPSHOT_TAG_VAL //描述标签点值的相关信息的结构
{
TAG_ID tagID; /* 标签点的唯一ID */
TIMESTAMP timeStamp; /* 秒级时间戳 */
unsigned short ms; /* 毫秒 */
unsigned char tagType; /*该标签点的值类型 */
unsigned char quality; /* 数据质量 */
unsigned char val[1]; /* 当前值,根据标签点数据类型的不同长度不一 ,变化范围1----128 ,这里用到了越界*/
};DBOP_API int DBOP_SetSnapshotValue ( IN TAG_ID tagID, IN struct DBOP_SNAPSHOT_TAG_VAL* pVal);
DBOP_API int DBOP_GetSnapshotValue ( IN TAG_ID tagID, OUT struct DBOP_SNAPSHOT_TAG_VAL* pVal, IN int bufLen);
2:现在需要在c#下面调用:[DllImport("dbop_dll.dll", EntryPoint = "DBOP_SetSnapshotValue", CharSet = CharSet.Ansi)]
public static extern int DBOP_SetSnapshotValue( uint tagID, APICommonDataStruct.DBOP_SNAPSHOT_TAG_VAL pVal);
[DllImport("dbop_dll.dll", EntryPoint = "DBOP_GetSnapshotValue", CharSet = CharSet.Ansi)]
public static extern int DBOP_GetSnapshotValue(uint tagID, ref DBOP_SNAPSHOT_TAG_VAL pVal, int bufLen); public struct DBOP_SNAPSHOT_TAG_VAL //描述标签点值的相关信息的结构
{
public uint tagID; /* 标签点的唯一ID */
public uint timeStamp; /* 秒级时间戳 */
public ushort ms; /* 毫秒 */
public byte tagType; /*该标签点的值类型 */
//[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)]
public byte quality; /* 数据质量 */
[MarshalAs(UnmanagedType.ByValArray, SizeConst =128)]
public byte [] val; /* 该标签点的值的第一个字节 */
};
其中最后一个字节数组取的前面变长结构体的最大长度3 现在的问题是我可以读取数据,但是无法将数据写入!希望各位知道的指教啊,感激不尽!
处理结构体
这里是指针[DllImport("dbop_dll.dll", EntryPoint = "DBOP_SetSnapshotValue", CharSet = CharSet.Ansi)]
public static extern int DBOP_SetSnapshotValue( uint tagID, APICommonDataStruct.DBOP_SNAPSHOT_TAG_VAL pVal); 这里却是类实例试一试加个 ref,也传指针。
[DllImport("dbop_dll.dll", EntryPoint = "DBOP_SetSnapshotValue", CharSet = CharSet.Ansi)]
public static extern int DBOP_SetSnapshotValue( uint tagID,ref APICommonDataStruct.DBOP_SNAPSHOT_TAG_VAL pVal);
Type could not be marshaled because the length of an embedded array instance does not match the declared length in the layout.这个时候传入的是数据类型为整形的值,字节数为4!
找不到例子和资料
typedef struct
{
char *RequestName,
int Count,
} ALERT_REQUEST; int DoAlertRequest(ALERT_REQUEST *pRequest);
Its corresponding managed version in C# is: Copy Code
struct AlertRequest
{
String RequestName;
int Count;
} class AlertClass
{
[DLLImport("ALERT.DLL", EntryPoint="DoAlertRequest",
CharSet=CharacterSet.Ansi)]
public static extern int DoRequest(ref AlertRequest Req);
}
The DllImportAttribute attribute annotates the metadata of the native method call. It notifies the common language runtime that the DoRequest method is in ALERT.DLL, that the name of the method is DoAllertRequest, and to marshal strings to ANSI because all strings in managed code are Unicode strings. A call to this method in C++ in the .NET Framework might look like this: Copy Code
AlertRequest Request = new AlertRequest()
Request.RequestName = "beep";
Request.Count = 10;
AlertClass.DoRequest(ref Request);
When the .NET Framework's common language runtime encounters the DoRequest, call it dynamically loads ALERT.DLL, gets the address of DoAlertRequest, builds an unmanaged version of the structure converting strings as needed, pushes a pointer to this structure, and calls DoAlertRequest. It cannot just pass a pointer to the structure because it contains an embedded String object. Given these constraints, the native DoRequest method cannot be called directly. Instead, an intermediate thunking call must wrap DoRequest. The following C# code is an example: Copy Code
class AlertClass
{
[DllImport("ALERT.DLL", EntryPoint="DoAlertRequestThunk")]
private static extern int DoRequestThunk(String RequestName, int Count); public static int DoRequest(ref AlertRequst Req)
{
return DoRequestThunk(Req.RequestName, Req.Count);
}
}
AlertClass still contains a method with the same signature as its counterpart on the .NET Framework. The .NET Compact Framework DoRequest is a managed routine that calls a private native routine. Notice that the fields of the structure have been broken out into separate argument in the call to the native routine because the String object within the structure would not be marshaled. The thunk wraps the native DoRequest. It builds an unmanaged version of the structure and performs the string conversion, as shown here in C++: Copy Code
int DoRequestThunk(wchar_t *RequestNameW, int Count)
{
ALERT_REQUEST Req;
int ReturnCode;
// CreateAnsiFromUnicodeString allocates and builds an ANSI
// version of the Unicode string.
Req.RequestName = CreateAnsiFromUnicodeString(RequestNameW);
if (Req.RequestName == NULL)
Return 0; Req.Count = Count; // This is the native DoRequest, not to be confused
// with the managed method of the same name.
ReturnCode = DoAlertRequest(&Req); free(Req.RequestName)
return ReturnCode;
}
DBOP_API int DBOP_SetSnapshotValue ( IN TAG_ID tagID, IN struct DBOP_SNAPSHOT_TAG_VAL* pVal);
DBOP_API int DBOP_GetSnapshotValue ( IN TAG_ID tagID, OUT struct DBOP_SNAPSHOT_TAG_VAL* pVal, IN int bufLen);
所以在C#中你应定义为:
[DllImport("dbop_dll.dll", EntryPoint = "DBOP_SetSnapshotValue", CharSet = CharSet.Ansi)]
public static extern int DBOP_SetSnapshotValue( uint tagID, ref APICommonDataStruct.DBOP_SNAPSHOT_TAG_VAL pVal);
[DllImport("dbop_dll.dll", EntryPoint = "DBOP_GetSnapshotValue", CharSet = CharSet.Ansi)]
public static extern int DBOP_GetSnapshotValue(uint tagID, ref DBOP_SNAPSHOT_TAG_VAL pVal, int bufLen);
加个ref还是前面的错误