Hi,
I'm not sure, but I may have found a memory leak between vb6 and .net. Of
course, it is possible that I just don't understand something correctly or I
did something wrong. In any event, what I've done is create a C# class
library that exposes an interface through COM. If I instantiate this
interface in vb6 it is never released. I included a finalize method and it
is never called. If I instantiate the same interface in C++ it is released
as expected and the finalize method is called. I understand that the
execution of the finalize method is non-deterministic. I've tried waiting
for extended periods and it is just never called from the vb app. I've
boiled it down to a very simple example. Below is a C# server, a C++
client, and a VB6 client. The finalize method is called everytime when the
C++ app exits and it is never called when the VB6 client exists. If you
compile these the VB6 app is a console app, so you'll have to run 'editbin
/SUBSYSTEM:CONSOLE' on the exe. If any can explain the behavior, I would
appreciate it.
Thanks
Steven
================= C#
using System;
using System.Runtime.InteropServices;
namespace MemLeak
{
/// <summary>
/// Summary description for IMemLeak.
/// </summary>
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[GuidAttribute("E2F25E23-40D4-4f9b-BC2F-0D6BA932DA31")]
[ComVisible(true)]
[CLSCompliant(false)]
public interface IMemLeak
{
void DummyMethod();
}
/// <summary>
/// Summary description for MemLeakObj.
/// </summary>
[ClassInterface(ClassInterfaceType.None)]
[GuidAttribute("66BAA837-CCA4-4a07-AC6C-8EFBE22928BB")]
[ProgId("MemLeak.MemLeakObj.1")]
[ComVisible(true)]
public class MemLeakObj : IMemLeak
{
public MemLeakObj()
{
Console.WriteLine("MemLeakObj: Constructor");
}
~MemLeakObj()
{
Console.WriteLine("MemLeakObj: Finalizer");
}
#region IMemLeak Members
public void DummyMethod()
{
Console.WriteLine("MemLeakObj: DummyMethod");
}
#endregion
}
}
================== VB6
Option Explicit
Public Const STD_OUTPUT_HANDLE = -11&
Public Declare Function stdout Lib "kernel32" Alias "GetStdHandle" _
(Optional ByVal Handletype As Long = STD_OUTPUT_HANDLE) As Long
Public Declare Function WriteFile Lib "kernel32" _
(ByVal hFile As Long, ByVal lpBuffer As Any, ByVal nNumberOfBytesToWrite As
Long, _
lpNumberOfBytesWritten As Long, Optional ByVal lpOverlapped As Long = 0&) As
Long
Sub Main()
Dim sWriteBuffer As String
Dim lBytesWritten As Long
Dim hStdOut As Long
sWriteBuffer = "MemLeak VB Client" & vbCrLf
hStdOut = stdout()
WriteFile hStdOut, sWriteBuffer, Len(sWriteBuffer), lBytesWritten
Dim o As Object
Set o = CreateObject("MemLeak.MemLeakObj.1")
Set o = Nothing
End Sub
==================== C++
// This is the main project file for VC++ application project
// generated using an Application Wizard.
#include "stdafx.h"
#include <objbase.h>
#define CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#using <mscorlib.dll>
using namespace System;
int _tmain()
{
// TODO: Please replace the sample code below with your own.
Console::WriteLine(S"MemLeak C++ Client");
::CoInitialize(NULL);
CLSID clsid;
HRESULT hr = ::CLSIDFromProgID(L"MemLeak.MemLeakObj.1", &clsid);
IDispatch *p = NULL;
hr = ::CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch,
(void**)&p);
p->Release();
_CrtDumpMemoryLeaks();
::CoUninitialize();
return 0;
}