Profile Picture

COM Interop

Posted By Steve Clevenger 12 Years Ago
Author
Message
Steve Clevenger
Posted 12 Years Ago
View Quick Profile
Forum Newbie

Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)

Group: Forum Members
Last Active: 11 Years Ago
Posts: 7, Visits: 1
Hi Support,

I’m attempting to create a COM Interop to a C# assembly I used to wrap a Nevron 3D Bar Chart. Depending on how I setup CoCreateInstance, it returns one of two HRESULTS:

1. 0x80040154 "Class not registered"
2. 0x80131532 COR_E_MISSINGMANIFESTRESOURCE

These errors indicate I’m unable to retrieve a pointer to my COM interface. I’m using a Windows 7 x64 operating system, but my assembly and COM Interop is built x86. It's possible I have a deployment or installation problem with the Nevron assemblies, but they all appear to be present (with one exception) in the GAC. Note that my assembly wrapper executes fine when Visual Studio 2010 hosted (no COM Interop).

It's easy enough for CoCreateInstance to return a pointer to a COM interface from a class which does essentially nothing. Here's a Microsoft example similar to what I'm trying to do.

I've included the CSharpServer.reg file contents created for this server (see below) using the following command with administrator privilege:

regasm.exe CSharpServer.dll /codebase /regfile:CSharpServer.reg

Aside from the Guids, class, and interface names in this example, the Nevron interface I use (previous post) has the same registry structure. I've included my registry entries at the very bottom of this e-mail, since I can only attach 3 files.

Steve C.

////////////////////////// MICROSOFT COM SERVER EXAMPLE //////////////////////////

// CSharpServer.cs COM Server
// compile with: /target:library
// post-build command: regasm CSharpServer.dll /tlb:CSharpServer.tlb

using System;
using System.Runtime.InteropServices;

namespace CSharpServer
{
// Since the .NET Framework interface and coclass have to behave as
// COM objects, we have to give them guids.
[Guid("DBE0E8C4-1C61-41f3-B6A4-4E2F353D3D05")]
public interface IManagedInterface
{
int PrintHi(string name);
}

[Guid("C6659361-1625-4746-931C-36014B146679")]
public class InterfaceImplementation : IManagedInterface
{
public int PrintHi(string name)
{
Console.WriteLine("Hello, {0}!", name);
return 33;
}
}
}

////////////////////////// MICROSOFT COM CLIENT EXAMPLE //////////////////////////

// Copyright (C) Microsoft Corporation. All rights reserved.

// cominteropPart2\COMClient.cpp
// Build this part of the sample with the command line:
// cl COMClient.cpp

#include
#include

#pragma warning (disable: 4278)

// To use managed-code servers like the C# server,
// we have to import the common language runtime:
#import raw_interfaces_only

// For simplicity, we ignore the server namespace and use named guids:
#if defined (USINGPROJECTSYSTEM)
#import "..\RegisterCSharpServerAndExportTLB\CSharpServer.tlb" no_namespace named_guids
#else // Compiling from the command line, all files in the same directory
#import "CSharpServer.tlb" no_namespace named_guids
#endif
int main(int argc, char* argv[])
{
IManagedInterface *cpi = NULL;
int retval = 1;

// Initialize COM and create an instance of the InterfaceImplementation class:
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(CLSID_InterfaceImplementation,
NULL,
CLSCTX_INPROC_SERVER,
IID_IManagedInterface,
reinterpret_cast(&cpi));

if (FAILED(hr))
{
printf("Couldn't create the instance!... 0x%x\n", hr);
}
else
{
if (argc > 1)
{
printf("Calling function.\n");
// The variable cpi now holds an interface pointer // to the managed interface.
// If you are on an OS that uses ASCII characters at the // command prompt, notice that the ASCII characters are
// automatically marshaled to Unicode for the C# code.

if (cpi->PrintHi(argv[1]) == 33)
retval = 0;

printf("Returned from function.\n");
}
else
printf ("Usage: COMClient \n");
cpi->Release();
cpi = NULL;
}

// Be a good citizen and clean up COM:
CoUninitialize();
return retval;
}


/////////////////////////////// CSharpServer.reg /////////////////////////////////

REGEDIT4

[HKEY_CLASSES_ROOT\CSharpServer.InterfaceImplementation]
@="CSharpServer.InterfaceImplementation"

[HKEY_CLASSES_ROOT\CSharpServer.InterfaceImplementation\CLSID]
@="{C6659361-1625-4746-931C-36014B146679}"

[HKEY_CLASSES_ROOT\CLSID\{C6659361-1625-4746-931C-36014B146679}]
@="CSharpServer.InterfaceImplementation"

[HKEY_CLASSES_ROOT\CLSID\{C6659361-1625-4746-931C-36014B146679}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="CSharpServer.InterfaceImplementation"
"Assembly"="CSharpServer, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///C:/Users/Steve/Documents/Visual Studio 2010/Projects/COMInterop/CSharpServer/bin/Debug/CSharpServer.dll"

[HKEY_CLASSES_ROOT\CLSID\{C6659361-1625-4746-931C-36014B146679}\InprocServer32\0.0.0.0]
"Class"="CSharpServer.InterfaceImplementation"
"Assembly"="CSharpServer, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///C:/Users/Steve/Documents/Visual Studio 2010/Projects/COMInterop/CSharpServer/bin/Debug/CSharpServer.dll"

[HKEY_CLASSES_ROOT\CLSID\{C6659361-1625-4746-931C-36014B146679}\ProgId]
@="CSharpServer.InterfaceImplementation"

[HKEY_CLASSES_ROOT\CLSID\{C6659361-1625-4746-931C-36014B146679}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]


///////////////////////////// NevronChartTest.reg ////////////////////////////////

// BELOW ARE THE REGISTRY ENTRIES FOR MY INTERFACE. COMPARE AGAINST THE
// CSharpServer.reg CONTENTS.

REGEDIT4

[HKEY_CLASSES_ROOT\NevronChartTest.NevronChart]
@="NevronChartTest.NevronChart"

[HKEY_CLASSES_ROOT\NevronChartTest.NevronChart\CLSID]
@="{112CA7D7-F682-4F22-BAD5-971B855887AF}"

[HKEY_CLASSES_ROOT\CLSID\{112CA7D7-F682-4F22-BAD5-971B855887AF}]
@="NevronChartTest.NevronChart"

[HKEY_CLASSES_ROOT\CLSID\{112CA7D7-F682-4F22-BAD5-971B855887AF}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="NevronChartTest.NevronChart"
"Assembly"="NevronChartTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///C:/Users/Steve/Documents/Visual Studio 2010/Projects/List/NevronChartTest/bin/Debug/NevronChartTest.dll"

[HKEY_CLASSES_ROOT\CLSID\{112CA7D7-F682-4F22-BAD5-971B855887AF}\InprocServer32\1.0.0.0]
"Class"="NevronChartTest.NevronChart"
"Assembly"="NevronChartTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///C:/Users/Steve/Documents/Visual Studio 2010/Projects/List/NevronChartTest/bin/Debug/NevronChartTest.dll"

[HKEY_CLASSES_ROOT\CLSID\{112CA7D7-F682-4F22-BAD5-971B855887AF}\ProgId]
@="NevronChartTest.NevronChart"

[HKEY_CLASSES_ROOT\CLSID\{112CA7D7-F682-4F22-BAD5-971B855887AF}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]


Nevron Support
Posted 12 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)

Group: Forum Members
Last Active: Last Week
Posts: 3,054, Visits: 4,009
Hello Steve,

So if you simplify the interface the class can be created? Which are the problematic methods that you have to remove in order to make it work?


Best Regards,
Nevron Support Team



Steve Clevenger
Posted 12 Years Ago
View Quick Profile
Forum Newbie

Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)

Group: Forum Members
Last Active: 11 Years Ago
Posts: 7, Visits: 1
Hi All,

As part of my evaluation, I need to add some kind of COM server, or COM Callable Wrapper (CCW) around a Nevron 3D Bar Chart implementation such that select interface entries can be called from existing unmanaged MFC C++. I'm new to COM, in general, but I have to think someone has walked this path before. I'm using Visual Studio 2010, and everything is built (and registered) for x86. The System and Nevron assemblies (except for Nevron.Diagram.WinForm) seem to be resident in the GAC.

I'm attempting to interface the .NET assemblies through the IChartInterface from MFC, but can never get a pointer to the interface. The problem is CoCreateInstance in the C++ client returns an HRESULT of 0x80040154 "Class not registered" unless the interface is simplified to the extent it can't do anything I need.

These are the Registry entries found for IChartInterface:

HKEY_CLASSES_ROOT\Interface\{415100CE-8BCD-45F2-AF10-ADBF84F9ECE1}
HKEY_CLASSES_ROOT\Wow6432Node\Interface\{415100CE-8BCD-45F2-AF10-ADBF84F9ECE1}
HKEY_CLASSES_ROOT\Wow6432Node\Interface\{415100CE-8BCD-45F2-AF10-ADBF84F9ECE1}\ProxyStubClsid32
(Default) {00020424-0000-0000-C000-000000000046}
HKEY_CLASSES_ROOT\Wow6432Node\Interface\{415100CE-8BCD-45F2-AF10-ADBF84F9ECE1}\TypeLib
(Default) {1E6F43BC-F79C-4E66-B9E6-3B60B220D1BE}
Value 1.0

The NevronChartTest TypeLib Guid is 1E6F43BC-F79C-4E66-B9E6-3B60B220D1BE in the AssemblyInfo.cs file in my project. All part of COM are marked as visible

During startup, a ProcMon.exe trace of Registry activity shows no access (whatsoever) involving the IChartInterface entries.


Here's an abbreviation of what I'm trying to do in Visual Studio 2010:

// C++ Client
#import "NevronChartTest.tlb" named_guids

using namespace NevronChartTest;

CMyDialog:nInitDialog()
{
NevronChartTest::IChartInterface *pIChartInterface = NULL;

hResult = CoInitialize(NULL);
hResult = CoCreateInstance (
CLSID_NevronChart, // in NevronChartTest.tli
NULL,
CLSCTX_INPROC_SERVER
IID_PPV_ARGS(&pIChartInterface)
);

CoUninitialize();

return (hResult ? FALSE : TRUE); // hResult: 0x80040154 "Class not registered"
}

// C# COM Server DLL
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Runtime.InteropServices;

using System.Threading;
using System.Windows.Forms;
using Nevron.Dom;
using Nevron.GraphicsCore;
using Nevron.Chart;
using Nevron.Chart.WinForm;

namespace NevronChartTest
{
[ToolboxItem(false)]
[Guid("415100CE-8BCD-45F2-AF10-ADBF84F9ECE1")]
public interface IChartInterface
{
void ChartInstance(bool bOrthogonal);

void AddTitle(string Name);

void AddBarData(NBarSeries bar, double x, double y);

void AddDataPoint(NRangeSeries series, double x1, double x2, double y1, double y2, double z1, double z2);

void ClearData();
}

[ComVisible(true)]
[Guid("112CA7D7-F682-4F22-BAD5-971B855887AF")]
public partial class NevronChart : Form, IChartInterface
{
NBarSeries barSeries;
NLabel title;
bool bDisplayOrthogonal;

public NevronChart()
{
bDisplayOrthogonal = true;

InitializeComponent();
}

// COM Entry Points...
public void ChartInstance(bool bOrthogonal)
{
bDisplayOrthogonal = bOrthogonal;

InitializeComponent();
}

public void AddTitle(string Name)
{
title = new NLabel(Name);
title.Dock = DockStyle.Top;
title.TextStyle.FontStyle = new NFontStyle("Times New Roman", 18, FontStyle.Italic);
title.TextStyle.FillStyle = new NColorFillStyle(Color.Blue);
}

public void AddBarData(NBarSeries bar, double x, double y)
{
bar.AddDataPoint(new NDataPoint(x - 0.5, y)); // 1..10
nChartControl1.Refresh();
}

public void AddDataPoint(NRangeSeries series, double x1, double x2, double y1, double y2, double z1, double z2)
{
series.XValues.Add(x1);
series.X2Values.Add(x2);
series.Values.Add(y1);
series.Y2Values.Add(y2);
series.ZValues.Add(z1);
series.Z2Values.Add(z2);
}

public void ClearData()
{
// clear data
barSeries.ClearDataPoints();
}

private void NevronChart_Load(object sender, System.EventArgs e)
{
Initialize();
}

private void Initialize()
{
// ...the usual stuff...
}

/// Required designer variable.
private System.ComponentModel.IContainer components = null;

/// Clean up any resources being used.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

private Nevron.Chart.WinForm.NChartControl nChartControl1;

// Windows Form Designer generated code

/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.

private void Initialize_Component()
{
/// ...the usual setup... (e.g a System EventHandler to call
/// NevronChart_Load(), etc.)
}
}

Steve C.



Similar Topics


Reading This Topic