what's wrong with this !

D

Droopy

I am making a managed C++ wrapper for calling legacy C++ code from C#.
I don't understand what's wrong with following code :

__gc public class SerialBuffer
{
private:
unsigned char __nogc*_buffer;
short _bufferNr;
bool _isUsed;
int _length;

public:

SerialBuffer (short bufferNr);
....
}

__gc public class TrspPortManaged
{
public:
static const short NbSerialBuffers = 128;
TrspPortManaged ();
....

private:
SerialBuffer *_buffers [];
UMTrspPort __nogc *_unmanaged;
....
}

....

TrspPortManaged::TrspPortManaged ()
{
_unmanaged = new UMTrspPort ();

_buffers = new SerialBuffer *[NbSerialBuffers];
SerialBuffer *sb;
for (int i = 1; i <= NbSerialBuffers; i++)
{
sb = new SerialBuffer (i);
_buffers [i - 1] = sb;
}
....
}

In TrspPortManaged constructor, the first iteration in for loop seems OK
(sb _buffer var = 0x07253240, keep the same value in _buffers [0])
The second iteration (i = 2), sb _buffer var = 0x07256ee8, buffer [1]->
_buffer = 0x00000000

What am I doing wrong ?

Thanks in advance for your help.

Droopy.
 
J

Jochen Kalmbach [MVP]

Hi Droopy!
I am making a managed C++ wrapper for calling legacy C++ code from C#.
I don't understand what's wrong with following code :

What error do you get?
Can you provide a small, complete repro-code?

TrspPortManaged::TrspPortManaged ()
{
_unmanaged = new UMTrspPort ();

_buffers = new SerialBuffer *[NbSerialBuffers];
SerialBuffer *sb;
for (int i = 1; i <= NbSerialBuffers; i++)
{
sb = new SerialBuffer (i);
_buffers [i - 1] = sb;
}
}

I can´t see anything bad...

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
D

Droopy

Hi Droopy!

What error do you get?
Can you provide a small, complete repro-code?

I can´t see anything bad...

OK, here it is a sample complete code that illustrate the problem :

1) IprWrapper.h + IprWrapper.cpp in a C++ dll project

// IprWrapper.h

#pragma once

using namespace System;

namespace IprWrapper
{
#pragma once

using namespace System;
using namespace System::Runtime::InteropServices;
__gc public class SerialBuffer
{
private:
unsigned char __nogc*_buffer;
short _bufferNr;
bool _isUsed;
int _length;

public:

SerialBuffer (short bufferNr);

__property bool get_IsUsed ()
{
return _isUsed;
}

__property void set_IsUsed (bool value)
{
_isUsed = value;
}

__property short get_BufferNumber ()
{
return _bufferNr;
}

__property void set_BufferNumber (short value)
{
_bufferNr = value;
}
};

//----- class TrspPortManaged -----------

__gc public class TrspPortManaged
{
public:
static const short BufferSize = 16;
static const short NbSerialBuffers = 128;

TrspPortManaged ();

private:
SerialBuffer *_buffers [];
};
}

// IprWrapper.cpp

#include "stdafx.h"

#include "IprWrapper.h"

namespace IprWrapper
{

TrspPortManaged::TrspPortManaged ()
{
_buffers = new SerialBuffer *[NbSerialBuffers];
SerialBuffer *sb;
for (int i = 1; i <= NbSerialBuffers; i++)
{
sb = new SerialBuffer (i);
_buffers [i - 1] = sb;
}
}

// SerialBuffer class

SerialBuffer::SerialBuffer (short bufferNr)
{
_buffer = new unsigned char [TrspPortManaged::BufferSize];
IsUsed = false;
_length = 0;
BufferNumber = bufferNr;
}
}

2) A simple C# windows application, using the C++ dll (project reference)

private void Form1_Load(object sender, System.EventArgs e)
{
IprWrapper.TrspPortManaged transport = new IprWrapper.TrspPortManaged ();
}

The problem is that, in the TrspPortManaged constructor, in the for loop,
sb->_buffer is changed (from 0x07512d40 to 0x00000000) when the following
line is executed :
_buffers [i - 1] = sb;

Usually, the first iteration works, the second fails.

Thanks in advance for your help.

Droopy.
 
W

Willy Denoyette [MVP]

Droopy said:
Hi Droopy!

What error do you get?
Can you provide a small, complete repro-code?

I can´t see anything bad...

OK, here it is a sample complete code that illustrate the problem :

1) IprWrapper.h + IprWrapper.cpp in a C++ dll project

// IprWrapper.h

#pragma once

using namespace System;

namespace IprWrapper
{
#pragma once

using namespace System;
using namespace System::Runtime::InteropServices;
__gc public class SerialBuffer
{
private:
unsigned char __nogc*_buffer;
short _bufferNr;
bool _isUsed;
int _length;

public:

SerialBuffer (short bufferNr);

__property bool get_IsUsed ()
{
return _isUsed;
}

__property void set_IsUsed (bool value)
{
_isUsed = value;
}

__property short get_BufferNumber ()
{
return _bufferNr;
}

__property void set_BufferNumber (short value)
{
_bufferNr = value;
}
};

//----- class TrspPortManaged -----------

__gc public class TrspPortManaged
{
public:
static const short BufferSize = 16;
static const short NbSerialBuffers = 128;

TrspPortManaged ();

private:
SerialBuffer *_buffers [];
};
}

// IprWrapper.cpp

#include "stdafx.h"

#include "IprWrapper.h"

namespace IprWrapper
{

TrspPortManaged::TrspPortManaged ()
{
_buffers = new SerialBuffer *[NbSerialBuffers];
SerialBuffer *sb;
for (int i = 1; i <= NbSerialBuffers; i++)
{
sb = new SerialBuffer (i);
_buffers [i - 1] = sb;
}
}

// SerialBuffer class

SerialBuffer::SerialBuffer (short bufferNr)
{
_buffer = new unsigned char [TrspPortManaged::BufferSize];
IsUsed = false;
_length = 0;
BufferNumber = bufferNr;
}
}

2) A simple C# windows application, using the C++ dll (project reference)

private void Form1_Load(object sender, System.EventArgs e)
{
IprWrapper.TrspPortManaged transport = new IprWrapper.TrspPortManaged ();
}

The problem is that, in the TrspPortManaged constructor, in the for loop,
sb->_buffer is changed (from 0x07512d40 to 0x00000000) when the following
line is executed :
_buffers [i - 1] = sb;

Usually, the first iteration works, the second fails.

Thanks in advance for your help.

Droopy.

Works for me, don't know how you are looking at the sb->_buffer pointer but
all of them are correctly set when I run your code.

Willy.
 
D

Droopy

Droopy said:
Hi Droopy!
I am making a managed C++ wrapper for calling legacy C++ code from
C#. I don't understand what's wrong with following code :

What error do you get?
Can you provide a small, complete repro-code?

I can´t see anything bad...

OK, here it is a sample complete code that illustrate the problem :

1) IprWrapper.h + IprWrapper.cpp in a C++ dll project

// IprWrapper.h

#pragma once

using namespace System;

namespace IprWrapper
{
#pragma once

using namespace System;
using namespace System::Runtime::InteropServices;
__gc public class SerialBuffer
{
private:
unsigned char __nogc*_buffer;
short _bufferNr;
bool _isUsed;
int _length;

public:

SerialBuffer (short bufferNr);

__property bool get_IsUsed ()
{
return _isUsed;
}

__property void set_IsUsed (bool value)
{
_isUsed = value;
}

__property short get_BufferNumber ()
{
return _bufferNr;
}

__property void set_BufferNumber (short value)
{
_bufferNr = value;
}
};

//----- class TrspPortManaged -----------

__gc public class TrspPortManaged
{
public:
static const short BufferSize = 16;
static const short NbSerialBuffers = 128;

TrspPortManaged ();

private:
SerialBuffer *_buffers [];
};
}

// IprWrapper.cpp

#include "stdafx.h"

#include "IprWrapper.h"

namespace IprWrapper
{

TrspPortManaged::TrspPortManaged ()
{
_buffers = new SerialBuffer *[NbSerialBuffers];
SerialBuffer *sb;
for (int i = 1; i <= NbSerialBuffers; i++)
{
sb = new SerialBuffer (i);
_buffers [i - 1] = sb;
}
}

// SerialBuffer class

SerialBuffer::SerialBuffer (short bufferNr)
{
_buffer = new unsigned char [TrspPortManaged::BufferSize];
IsUsed = false;
_length = 0;
BufferNumber = bufferNr;
}
}

2) A simple C# windows application, using the C++ dll (project
reference)

private void Form1_Load(object sender, System.EventArgs e)
{
IprWrapper.TrspPortManaged transport = new
IprWrapper.TrspPortManaged ();
}

The problem is that, in the TrspPortManaged constructor, in the for
loop, sb->_buffer is changed (from 0x07512d40 to 0x00000000) when
the following line is executed :
_buffers [i - 1] = sb;

Usually, the first iteration works, the second fails.

Thanks in advance for your help.

Droopy.

Works for me, don't know how you are looking at the sb->_buffer
pointer but all of them are correctly set when I run your code.

Willy.

I just added _buffers in Watch list.
But you are wright, if I make more iterations in the for loop, the _buffer
value is updated with some "delay".
For example, before I execute iteration 10, _buffer = 0x00000000 for all
_buffer in _buffers array with index > 3 (I mean from _buffers [3] to
_buffers [9]).
After the execution of iteration 10, _buffers [3] is updated with a value !
= 0x00000000 !

May be it is the way the Watch window is working.

So I just added a Dump function called just after the TrspPortManaged
constructor.
At that time, all _buffer pointer are set but from item #27 to item #127,
they all have the same value = 0x00936528 !

Thanks for your help.

Droopy.
 
D

Droopy

Droopy said:
Hi Droopy!
I am making a managed C++ wrapper for calling legacy C++ code from
C#. I don't understand what's wrong with following code :

What error do you get?
Can you provide a small, complete repro-code?

I can´t see anything bad...


OK, here it is a sample complete code that illustrate the problem :

1) IprWrapper.h + IprWrapper.cpp in a C++ dll project

// IprWrapper.h

#pragma once

using namespace System;

namespace IprWrapper
{
#pragma once

using namespace System;
using namespace System::Runtime::InteropServices;
__gc public class SerialBuffer
{
private:
unsigned char __nogc*_buffer;
short _bufferNr;
bool _isUsed;
int _length;

public:

SerialBuffer (short bufferNr);

__property bool get_IsUsed ()
{
return _isUsed;
}

__property void set_IsUsed (bool value)
{
_isUsed = value;
}

__property short get_BufferNumber ()
{
return _bufferNr;
}

__property void set_BufferNumber (short value)
{
_bufferNr = value;
}
};

//----- class TrspPortManaged -----------

__gc public class TrspPortManaged
{
public:
static const short BufferSize = 16;
static const short NbSerialBuffers = 128;

TrspPortManaged ();

private:
SerialBuffer *_buffers [];
};
}

// IprWrapper.cpp

#include "stdafx.h"

#include "IprWrapper.h"

namespace IprWrapper
{

TrspPortManaged::TrspPortManaged ()
{
_buffers = new SerialBuffer *[NbSerialBuffers];
SerialBuffer *sb;
for (int i = 1; i <= NbSerialBuffers; i++)
{
sb = new SerialBuffer (i);
_buffers [i - 1] = sb;
}
}

// SerialBuffer class

SerialBuffer::SerialBuffer (short bufferNr)
{
_buffer = new unsigned char [TrspPortManaged::BufferSize];
IsUsed = false;
_length = 0;
BufferNumber = bufferNr;
}
}

2) A simple C# windows application, using the C++ dll (project
reference)

private void Form1_Load(object sender, System.EventArgs e)
{
IprWrapper.TrspPortManaged transport = new
IprWrapper.TrspPortManaged ();
}

The problem is that, in the TrspPortManaged constructor, in the for
loop, sb->_buffer is changed (from 0x07512d40 to 0x00000000) when
the following line is executed :
_buffers [i - 1] = sb;

Usually, the first iteration works, the second fails.

Thanks in advance for your help.

Droopy.

Works for me, don't know how you are looking at the sb->_buffer
pointer but all of them are correctly set when I run your code.

Willy.

I just added _buffers in Watch list.
But you are wright, if I make more iterations in the for loop, the
_buffer value is updated with some "delay".
For example, before I execute iteration 10, _buffer = 0x00000000 for
all _buffer in _buffers array with index > 3 (I mean from _buffers [3]
to _buffers [9]).
After the execution of iteration 10, _buffers [3] is updated with a
value ! = 0x00000000 !

May be it is the way the Watch window is working.

So I just added a Dump function called just after the TrspPortManaged
constructor.
At that time, all _buffer pointer are set but from item #27 to item
#127, they all have the same value = 0x00936528 !

Thanks for your help.

Droopy.

I changed some project options and all pointers seem OK now.
I enabled the "Enable Unmanaged Debugging" property from the Windows
application (in Configuration Properties->Debugging).
It reports memory leaks.
There is something I am missing here because I use managed C++.
What should I "delete" or "dispose" ?

Thanks in advance,

Droopy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top