Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / March 2007

Tip: Looking for answers? Try searching our database.

Buffer Overrun when .net event fires to a c++ app

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Chris Priest - 26 Mar 2007 10:41 GMT
Hi,

We are trying to implement COM inside our .NET c# application, that
needs to be called from a C++ app.

While we can get the properties and methods to work just fine, the C++
client has an issue with the events.

The C++ client can see and register interest in the c# event just fine,
I can debug the .net code and see that the C++ has registered interest,
but as soon as the .net app fires the event, the C++ app dies with a
Buffer Overrun exception.

The event has no parameters, I've worked based on the information
available from Microsoft, but I cannot fathom out why this is happening.

Unfortunately I am not a C++ programmer, but a C# programmer, so the C++
code makes little sense!

Does any one have any thoughts on why this might be happening?

The relevant code is shown below:

Interface in .NET DLL:

namespace ClientControl
{
    [Guid("04F3C372-9E85-442d-B7E4-D6966E14BD0E")]
    [ComVisible(true)]
    public interface IClientControl
    {
        void Login(string serverAddress, int serverPort, string username,
string password);
        void Logout();
        void Dispose();
        void ChangeStatus(string status);
        string CurrentStatus { get; }
        string Version { get; }
    }

    [Guid("548B0682-AA8E-437c-839C-877BF9CADE3B")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)]
    [ComVisible(true)]

    public interface IClientControl_Events
    {
        [DispId(1)]
        void StatusChanged();
        [DispId(2)]
        void Notification();
    }

}

Main Class File:

public delegate void StatusChangedEventHandler();
    public delegate void NotificationEventHandler();

    [ClassInterface(ClassInterfaceType.None),ComSourceInterfaces(typeof(IClientControl_Events))]
    [Guid("6612B82C-3C47-4c99-AE5E-FC83C397AF2C")]
    [ComVisible(true)]
    public partial class ClientControl : UserControl, IClientControl,
IDisposable   

 public event NotificationEventHandler Notification;
 public event StatusChangedEventHandler StatusChanged;

Code to fire event:

if (StatusChanged != null)
{
StatusChanged();
}

If anyone has any pointers, I'd love to hear them!

Best Regards
Chris
Chris Priest - 26 Mar 2007 10:54 GMT
In Addition to the last post:

I get the following when debugging the .net code (using the C++ exe as
the test container for debug)

-----------

ERROR : Unable to load Typelibrary. (HRESULT = 0x8002801d)
    Verify TypelibID and major version specified with
    IDispatchImpl, CStockPropImpl, IProvideClassInfoImpl or
IProvideCLassInfo2Impl
A first chance exception of type
'System.Runtime.InteropServices.COMException' occurred in ClientControl.dll
An unhandled exception of type
'System.Runtime.InteropServices.COMException' occurred in ClientControl.dll

Additional information: Library not registered. (Exception from HRESULT:
0x8002801D (TYPE_E_LIBNOTREGISTERED))

------------

This occurs as soon as the .net code tries to raise the event.

Regards
Chris
Jayme Pechan - 26 Mar 2007 16:36 GMT
You might look at your C++ event sink class.  I suspect your error is
probably in there.  Maybe you could show your event sink implementation from
your C++ code here.  The C# code looks fine to me.

> Hi,
>
[quoted text clipped - 74 lines]
> Best Regards
> Chris
Chris Priest - 26 Mar 2007 17:14 GMT
Hi Jayme,

I think this is what you are referring to :) :

// ClientControlEventSink.h

#pragma once
#import "ClientControl.tlb" named_guids raw_interfaces_only
#define IDC_ClientControl 998

// CClientControlEventSink command target

class CClientControlEventSink : public CCmdTarget
{
    DECLARE_DYNAMIC(CClientControlEventSink)

public:
    CClientControlEventSink();
    virtual ~CClientControlEventSink();

    virtual void OnFinalRelease();

    // ClientControl overrides
    void OnStatusChanged();

protected:
    DECLARE_MESSAGE_MAP()
    DECLARE_DISPATCH_MAP()
    DECLARE_INTERFACE_MAP()

// ClientControlEventSink.cpp : implementation file
//

#include "stdafx.h"
#include "tryclientcontrol.h"
#include "ClientControlEventSink.h"

// CClientControlEventSink

IMPLEMENT_DYNAMIC(CClientControlEventSink, CCmdTarget)

CClientControlEventSink::CClientControlEventSink()
{
    EnableAutomation();
}

CClientControlEventSink::~CClientControlEventSink()
{
}

void CClientControlEventSink::OnFinalRelease()
{
    // When the last reference for an automation object is released
    // OnFinalRelease is called.  The base class will automatically
    // deletes the object.  Add additional cleanup required for your
    // object before calling the base class.

    CCmdTarget::OnFinalRelease();
}

BEGIN_MESSAGE_MAP(CClientControlEventSink, CCmdTarget)
END_MESSAGE_MAP()

BEGIN_DISPATCH_MAP(CClientControlEventSink, CCmdTarget)
 DISP_FUNCTION_ID(CClientControlEventSink,"StatusChanged", 0x00000001,
OnStatusChanged,VT_EMPTY,VTS_I4 VTS_I4)
END_DISPATCH_MAP()

// Note: we add support for IID_IClientControlEventSink to support
typesafe binding
//  from VBA.  This IID must match the GUID that is attached to the
//  dispinterface in the .IDL file.

// {6998F069-5D1D-45A3-9E42-384B6C5FA9B1}
//static const IID IID_IClientControlEventSink =
//{ 0x6998F069, 0x5D1D, 0x45A3, { 0x9E, 0x42, 0x38, 0x4B, 0x6C, 0x5F,
0xA9, 0xB1 } };
static const IID IID_IClientControlEventSink =
   { 0x548B0682, 0xAA8E, 0x437C, { 0x83, 0x9C, 0x87, 0x7B, 0xF9, 0xCA,
0xDE, 0x3B } };

BEGIN_INTERFACE_MAP(CClientControlEventSink, CCmdTarget)
    INTERFACE_PART(CClientControlEventSink,
ClientControl::DIID_IClientControl_Events, Dispatch)
END_INTERFACE_MAP()

// CClientControlEventSink message handlers
void CClientControlEventSink::OnStatusChanged()
{
    int i = 1000;
}

// ATlClientContainer.h : Declaration of the CATlClientContainer

#pragma once

#include "resource.h"       // main symbols

#include <atlhost.h>
#include <string>

#import "ClientControl.tlb" named_guids raw_interfaces_only
#define IDC_ClientControl 998

// CATlClientContainer
class CATlClientContainer;
typedef    IDispEventImpl<IDC_ClientControl, CATlClientContainer,
&ClientControl::DIID_IClientControl_Events,
            &ClientControl::LIBID_ClientControl> VoipIMControlEvent;

class CATlClientContainer :
    public CAxDialogImpl<CATlClientContainer>,
    public VoipIMControlEvent
{
public:
    CATlClientContainer()
    {
    }

    ~CATlClientContainer()
    {
    }

    enum { IDD = IDD_ATLCLIENTCONTAINER };

BEGIN_MSG_MAP(CATlClientContainer)
    MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
    MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
    CHAIN_MSG_MAP(CAxDialogImpl<CATlClientContainer>)
END_MSG_MAP()

BEGIN_SINK_MAP(CATlClientContainer)
    //Make sure the Event Handlers have __stdcall calling convention
    SINK_ENTRY_EX(IDC_ClientControl,
ClientControl::DIID_IClientControl_Events, 0x00000001, StatusChanged)
    SINK_ENTRY_EX(IDC_ClientControl,
ClientControl::DIID_IClientControl_Events, 0x00000002, Notification)
END_SINK_MAP()

// Handler prototypes:
//  LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled);
//  LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl,
BOOL& bHandled);
//  LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);

    LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled);
    LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);

protected:
    // Events
    VOID __stdcall StatusChanged()
    {

    }

    VOID __stdcall Notification()
    {
        //OnClientControlNotification();
    }
private:
    CComPtr<ClientControl::IClientControl> m_pClientControl;
    CAxWindow m_VoipWnd;
};

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.