Hello,
I am working on a program for instrumentation hardware using Visual Studio C++ on the .NET 2003 framework. The code would work fine on XP, but we're trying to get everything on Windows 7. Almost all the conversion problems have been handled, but a particular string still has its problems. They compile fine, but when I run tests using the hardware, it throws up a buffer overflow exception. I have tried converting the String class back to a character array (using Marshalling attribute of the System::Runtime::InteropServices) so that the function can take in the character array parameter as defined in its arguments. But on compiling I now get the following error(s):
Code:
21462 error LNK2022: metadata operation failed (80131188) : Inconsistent field declarations in duplicated types (types: Pxi6509; fields: DeviceDescriptorChar): (0x04000014).
21462 fatal error LNK1255: link failed because of metadata errors
I believe this has something to do with the ordering of header files, but I can't put a finger on which one and where. Hoping somebody would know.
The code is as:
Code:
#include "stdafx.h"
#include "PXI6509.h"
#include <stdio.h>
using namespace System;
using namespace System::Runtime::InteropServices;
Pxi6509::Pxi6509(int DeviceNo)
{
char ErrBuf [2048];
Char ErrorString[] = new Char __gc[2048];
int err;
Pxi6509::DeviceDescriptor = String::Format(S"PXI1Slot{0}", DeviceNo.ToString());
Pxi6509::DeviceDescriptorChar = (char*)(void*)Marshal::StringToHGlobalAnsi(DeviceDescriptor);
Marshal::FreeHGlobal(DeviceDescriptorChar);
PortDirection = new int __gc[12];
DioPort = new TaskHandle __gc[12];
TaskHandle TempHandle;
for(int idx = 0; idx < 12; idx++)
{
err = DAQmxCreateTask ("", &TempHandle);
if(err)
{
DAQmxGetExtendedErrorInfo(ErrBuf,2048);
for(int iy = 0; iy < 2048; iy++)
ErrorString[iy] = ErrBuf[iy];
String* Error = String::Format(S"Error Encountered in DAQmxCreateTask() for DioPort[{0}]: {1}", idx.ToString(), ErrorString->ToString());
throw new System::Exception(Error);
}
else
{
DioPort[idx] = TempHandle;
}
}
if((DeviceNo >= 0) && (DeviceNo < 9))
{
DeviceNumber = DeviceNo;
}
else
{
throw new Pxi6509DioException(S"Pxi6509::Pxi6509(). Device Number falls outside the range of this PXI Chassis");
}
}
Pxi6509::~Pxi6509()
{
for(int idx = 0; idx < 12; idx++) {
DAQmxStopTask(DioPort[idx]);
DAQmxClearTask(DioPort[idx]);
}
DAQmxResetDevice(Pxi6509::DeviceDescriptorChar);
}
void Pxi6509::ConfigureDioDirection(Pxi6509Direction Direction, Ports Port)
{
char ErrBuf [2048];
Char ErrorString[] = new Char __gc[2048];
int err;
Pxi6509::DeviceDescriptor = String::Format(S"PXI1Slot{0}", DeviceNo.ToString());
Pxi6509::DeviceDescriptorChar = (char*)Marshal::StringToHGlobalAnsi(DeviceDescriptor).ToPointer();
Marshal::FreeHGlobal(IntPtr(DeviceDescriptorChar));
PortDirection = new int __gc[12];
DioPort = new TaskHandle __gc[12];
TaskHandle TempHandle;
for(int idx = 0; idx < 12; idx++)
{
err = DAQmxCreateTask ("", &TempHandle);
if(err)
{
DAQmxGetExtendedErrorInfo(ErrBuf,2048);
for(int iy = 0; iy < 2048; iy++)
ErrorString[iy] = ErrBuf[iy];
String* Error = String::Format(S"Error Encountered in DAQmxCreateTask() for DioPort[{0}]: {1}", idx.ToString(), ErrorString->ToString());
throw new System::Exception(Error);
}
else
{
DioPort[idx] = TempHandle;
}
}
if((DeviceNo >= 0) && (DeviceNo < 9))
{
DeviceNumber = DeviceNo;
}
else
{
throw new Pxi6509DioException(S"Pxi6509::Pxi6509(). Device Number falls outside the range of this PXI Chassis");
}
}
Pxi6509::~Pxi6509()
{
for(int idx = 0; idx < 12; idx++) {
DAQmxStopTask(DioPort[idx]);
DAQmxClearTask(DioPort[idx]);
}
DAQmxResetDevice(Pxi6509::DeviceDescriptorChar);
void Pxi6509::ConfigureDioDirection(Pxi6509Direction Direction, Ports Port)
{
char ErrBuf [2048];
Char ErrorString[] = new Char __gc[2048];
int err;
char* PhyPortChar = (char*)Marshal::StringToHGlobalAnsi(PhyPort).ToPointer();
Marshal::FreeHGlobal(IntPtr(PhyPortChar));
if(Direction == Pxi6509Direction::Output) {
err = DAQmxCreateDOChan(DioPort[int(Port)], PhyPortChar,"",DAQmx_Val_ChanForAllLines);
PortDirection[int(Port)] = 1;
}
else {
err = DAQmxCreateDIChan(DioPort[int(Port)], PhyPortChar,"",DAQmx_Val_ChanForAllLines);
PortDirection[int(Port)] = 0;
}
if(err)
{
DAQmxGetExtendedErrorInfo(ErrBuf,2048);
for(int idx = 0; idx < 2048; idx++)
ErrorString[idx] = ErrBuf[idx];
String* Error = String::Format(S"Error Encountered in Pxi6509::ConfigureDioDirection() DAQmxCreateDIOChan: {0}", ErrorString->ToString());
throw new System::Exception(Error);
}
err = DAQmxStartTask(DioPort[int(Port)]);
if(err) {
DAQmxGetExtendedErrorInfo(ErrBuf,2048);
for(int idx = 0; idx < 2048; idx++)
ErrorString[idx] = ErrBuf[idx];
String* Error = String::Format(S"Error Encountered in Pxi6509::ConfigureDioDirection() DAQmxStartTask(): {0}", ErrorString->ToString());
throw new System::Exception(Error);
}
}
void Pxi6509::DigitalOutput(Ports Port, uInt8 Data)
{
char ErrBuf [2048];
Char ErrorString[] = new Char __gc[2048];
int err;
int32 sampsWritten;
if(Pxi6509::PortDirection[int(Port)]) {
err = DAQmxWriteDigitalU8 (DioPort[int(Port)], 1, 1, 10.0, DAQmx_Val_GroupByChannel, &Data, &sampsWritten, NULL);
if(err) {
DAQmxGetExtendedErrorInfo(ErrBuf,2048);
for(int idx = 0; idx < 2048; idx++)
ErrorString[idx] = ErrBuf[idx];
String* Error = String::Format(S"Error Encountered in Pxi6509::DigitalOutput() DAQmxWriteDigitalScalarU32(): {0}", ErrorString->ToString());
throw new System::Exception(Error);
}
}
else {
throw new System::Exception(S"Pxi6509::DigitalOutput(): You are trying to write to a DIO port that's configured as an Input!");
}
uInt8 Pxi6509::DigitalInput(Ports Port)
{
char ErrBuf [2048];
Char ErrorString[] = new Char __gc[2048];
int err;
int32 sampsRead =0;
uInt8 Data;
if(PortDirection[int(Port)] == 0) {
err = DAQmxReadDigitalU8 (DioPort[int(Port)], 1, 1.0, DAQmx_Val_GroupByChannel, &Data, 1, &sampsRead, NULL);
if(err) {
DAQmxGetExtendedErrorInfo(ErrBuf,2048);
for(int idx = 0; idx < 2048; idx++)
ErrorString[idx] = ErrBuf[idx];
String* Error = String::Format(S"Error Encountered in Pxi6509::DigitalInput() DAQmxReadDigitalScalarU32(): {0}", ErrorString->ToString());
throw new System::Exception(Error);
}
}
else {
throw new System::Exception(S"Pxi6509::DigitalInput(): You are trying to Read from a DIO port that's configured as an Output!");
}
return (Data);
} // Pxi6509::DigitalInput()