When I Call a function (TxProtocol) in my dll, VS show this error:
Attempted to read or write protected memory. This is usually an indication that other memory is corrupt.
DLL Source
Code:
//---------------------------------------------------------------------------
#include <windows.h>
//---------------------------------------------------------------------------
// Important note about DLL memory management when your DLL uses the
// static version of the RunTime Library:
//
// If your DLL exports any functions that pass String objects (or structs/
// classes containing nested Strings) as parameter or function results,
// you will need to add the library MEMMGR.LIB to both the DLL project and
// any other projects that use the DLL. You will also need to use MEMMGR.LIB
// if any other projects which use the DLL will be performing new or delete
// operations on any non-TObject-derived classes which are exported from the
// DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases,
// the file BORLNDMM.DLL should be deployed along with your DLL.
//
// To avoid using BORLNDMM.DLL, pass string information using "char *" or
// ShortString parameters.
//
// If your DLL uses the dynamic version of the RTL, you do not need to
// explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------
enum Protocol{
pStx, //byte 0
pIdSlave,
pIdMaster,
pCommandNumHi,
pCommandNumLo,
pParamNumHi,// escluso comand min 0 se nao tem parameters
pParamNumLo,
pCommand, //bite 7
// par1 para slave tem sempre 1 parameter ack ou nak
// par2
// ...
// parn
pChkHi, //ese id indica 8 entao o real byte (8 + ParamNum)->mChkHi+ParamNum
pChkLo, //ese id indica 9 usare ->mChkLo+ParamNum
pEtx //ese id indica 10 usare ->mEtx+ParamNum
};
#define MinProtLen 11
#define pAck 8
#define FstSlavePar 9
#define FstMasterPar 8
#define STX 2U
#define ID_SLAVE 0U
#define ID_MASTER 1U
#define ACK 6U
#define NAK 21U
#define ETX 3U
#define NET_ERR_OK 0
#define NET_ERR_STX 1
#define NET_ERR_NODE_TX 2
#define NET_ERR_NODE_RX 3
#define NET_ERR_MSG_NUM_LOW 4
#define NET_ERR_MSG_NUM_HIG 5
#define NET_ERR_CHK 6
#define NET_ERR_ETX 7
#define NET_ERR_LOWPAR 8
#define NET_ERR_TOOPAR 9
#define WORDL(x) *(BYTE *)(&x)
#define WORDH(x) *((BYTE *)(&x)+1)
typedef struct{
BYTE IdSlave;
BYTE IdMaster;
WORD cmd_num; /* Numero complessivo di Comandi ricevuti */
BYTE Command;
WORD num_Par; /* Numero di bytes da ricevere */
BYTE *Par;//[MAX_RX]; /* Messaggio ricevuto */
} TPar;
#pragma argsused
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
return 1;
}
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport) int RxProtocol(TPar *RxOut,BYTE *InRx,WORD InRxLen){
WORD uw,uw2;
BYTE ub,ub2;
//int i,j;
if(InRxLen>MinProtLen){
if(InRx[pStx]==STX){
if(InRx[pIdSlave]==ID_SLAVE){
if(InRx[pIdMaster]==ID_MASTER){
WORDH((*RxOut).num_Par)=InRx[pParamNumHi];
WORDL((*RxOut).num_Par)=InRx[pParamNumLo];
WORDH((*RxOut).cmd_num)=InRx[pCommandNumHi];
WORDL((*RxOut).cmd_num)=InRx[pCommandNumLo];
(*RxOut).IdSlave=InRx[pIdSlave];
(*RxOut).IdMaster=InRx[pIdMaster];
if(InRxLen>=((*RxOut).num_Par+MinProtLen)){
if(InRx[(*RxOut).num_Par+pEtx]==ETX){
uw2=0;
for(uw=1;uw<=pCommand+(*RxOut).num_Par;uw++)
uw2+=InRx[uw];
ub=WORDH(uw2);
ub2=WORDL(uw2);
if((InRx[uw]==ub)&&(InRx[uw+1]==ub2)){
if(InRx[pAck]==ACK){
if(((*RxOut).num_Par+MinProtLen)==InRxLen){
(*RxOut).Command=InRx[pCommand];
(*RxOut).Par=&InRx[FstSlavePar];
return(NET_ERR_OK);
}else
return(NET_ERR_TOOPAR);
}else
return(NAK);
}else
return(NET_ERR_CHK);
}else
return(NET_ERR_ETX);
}else
return(NET_ERR_LOWPAR);
}else
return(NET_ERR_NODE_RX);
}else
return(NET_ERR_NODE_TX);
}else
return(NET_ERR_STX);
}else
return(NET_ERR_MSG_NUM_LOW);
}
extern "C" __declspec(dllexport) WORD TxProtocol(TPar *InTx,BYTE *OutTx){
WORD uw,chksm;
OutTx[pStx]=STX;
OutTx[pIdSlave]=ID_SLAVE;
OutTx[pIdMaster]=ID_MASTER;
OutTx[pCommandNumHi]=WORDH((*InTx).cmd_num); // num parh
OutTx[pCommandNumLo]=WORDL((*InTx).cmd_num); // num parl
OutTx[pCommand]=(*InTx).Command;
OutTx[pParamNumHi]=WORDH((*InTx).num_Par); // num parh
OutTx[pParamNumLo]=WORDL((*InTx).num_Par); // num parl
for(uw=0;uw<(*InTx).num_Par;uw++)
OutTx[FstMasterPar+uw]=(*InTx).Par[uw];
chksm=0;
for(uw=1;uw<=(*InTx).num_Par+pCommand;uw++)
chksm+=OutTx[uw];
OutTx[uw++]=WORDH(chksm);
OutTx[uw++]=WORDL(chksm);
OutTx[uw++]=ETX;
return(uw);
}
C# Code
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace DLLBorland
{
class Program
{
public struct TPar
{
public byte IdSlave;
public byte IdMaster;
public int cmd_num;
public byte Command;
public int num_Par;
public byte[] parametros;
} ;
[DllImport(@"C:\Temp\teste\Project1.dll", EntryPoint = "TxProtocol", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
private static extern int TxProtocol(TPar parametros, ref byte[] teste);
static void Main(string[] args)
{
byte[] testebytes;
TPar parametros = new TPar();
parametros.IdSlave = (byte)1;
parametros.IdMaster = (byte)1;
parametros.cmd_num = 1;
parametros.Command = (byte)10;
parametros.num_Par = 1;
System.Text.ASCIIEncoding encoding=new System.Text.ASCIIEncoding();
parametros.parametros = Encoding.ASCII.GetBytes("TESTE PARAMETRO");
testebytes = new byte[512];
TxProtocol(parametros, ref testebytes);
testebytes[0] = 0;
}
}
}