C++/Dll help

Advertisement


Question
ok i am trying to make a dll, that in c++.net that i can access from vb.net.  I made a Class library(.net) project.  I ccan get it to compile and i can add it to my vb project but i can figure out how to access the functions with in.

this is the code i have
//////////////sink.h
// sink.h

#pragma once
#include <dshow.h>
#include <Sbe.h>

using namespace System;

namespace sink
{
  public __gc class Class1
  {
     // TODO: Add your methods for this class here.
     void sink::Class1::sinkfile(LPSTR szFileName,IBaseFilter *FileWriteFilter);
  };
  
}
/////////////sink.cpp
// This is the main DLL file.
#include <afxdisp.h>
#include "stdafx.h"

#include "sink.h"

#include <atlconv.h>
//sinkfileLIBRARY   sink
void sink::Class1::sinkfile(LPSTR szFileName,IBaseFilter *FileWriteFilter)
{
     USES_CONVERSION;
     HRESULT hr;      
     IFileSinkFilter   *m_pFileWriterControl;
     hr=FileWriteFilter->QueryInterface(IID_IFileSinkFilter, (void**)&m_pFileWriterControl);
     if (SUCCEEDED(hr))
        hr = m_pFileWriterControl->SetFileName(T2W(szFileName), 0);
}
////////////sink.def

LIBRARY   sink


Answer
First I shall apologise for any shortcomings in this answer. Your question is not really a C++ question as it related to using a specific implementation of C++ with an environment for which non-standard extensions and rules apply - namely .NET and the CLR together with VB .NET which obviously has little to do with C++. Secondly it is also a variation on C++ that I have not un until today had to get to grips with. I am in no way a .NET or VB expert...

However I would suggest that if you are using C++ in managed mode to work with other .NET citizens such as VB .NET then you should only use CLR compatible types when passing data in and out of functions. For example do not pass LPCSTR and the like, pass .NET framework System::String types around instead (in fact it seems that GC pointers to System::String and the like are what should be passed). It seems that a pointer to a CLR controlled type such as System::String will be __gc pointers by default and pointers to non-CLR types will _not_ be GC pointers by default i.e. they will be __nogc pointers to the application's C++ heap or wherever.

Of course you should really read up on the rules and options pertaining to using C++ and types with the .NET CLR environment. Try the MSDN library under such sections as .NET Development / Visual Studio .NET / Visual C++ / Managed Extensions for C++ Programming - all of this may be of interest but there are various parts that may be of particular use - the sections under the Migration Guide area for example. If you do not have a local copy of the MSDN library then you can find it online at http://www.msdn.microsoft.com/ - however as a version of this is in fact the documentation for Visual Studio .NET then I see no reason why you do not have a local copy available.

Now on the VB .NET side you need to add a reference to your managed C++ class library assembly to the VB .NET project - you will notice the references pseudo folder for the project in the solution explorer - right clicking on this and selecting add references brings up a tabbed dialog. Assuming your Managed C++ class library project is part of the same solution then you should be able to locate it listed on the Projects tab.

I tried your scenario out using a simple hello world type of application. In fact it uses a managed C++ class library project called ManagedCPPLib which contains a class called Greeting:

// ManagedCPPLib.h

#pragma once

using namespace System;

namespace ManagedCPPLib
{
       public __gc class Greeting
       {
       public:
         Greeting( String __gc * greet )
         : mGreet( greet )
         {
         }
     
         String __gc *  Hi( String __gc * name );

       private:
         String  __gc * mGreet;
     
       };
}

Note that I have played safe and explicitly made all pointers __gc pointers and that I pass around CLR System::String pointers. This is my first attempt at managed C++ after all!

The idea is that a greeting instance's Hi member function will return a greeting string which uses the name it is passed combined with the greeting string it was constructed with - so if we have a Greeting object like so:

       Greeting greet(S"Hi ");
       greet( S"John");

Would return "Hi John" (S appears to be another MS extension to C++ used to create literal CLR System::String objects).

The implementation of Greeting::Hi looks like so:

// This is the main DLL file.

#include "stdafx.h"

#include "ManagedCPPLib.h"

namespace ManagedCPPLib
{
       String __gc * Greeting::Hi( String __gc * name )
       {
         String * greetingParts __gc [] = { mGreet, name };
         return  String::Concat(greetingParts);
       }
}

Next I created a VB .NET Windows project in the same solution and added a Users Name edit box for a name to be entered a Greet button to trigger a call to ManagedCPPLib:: Greeting::Hi and a Greeting label to display the results to the automatically created form. I added a reference to ManagedCPPLib to this project then added a click handler for the Greet button:

 Private Sub Greet_Click(ByVal sender As System.Object
         , ByVal e As System.EventArgs
         ) Handles Greet.Click
 
         If UsersName.Text.Length > 0 Then

         Dim greet As New ManagedCPPLib.Greeting("Hi ")
         Greeting.Text = greet.Hi(UsersName.Text)

         End If
 
 End Sub

As this is my first venture into this area my example is probably not the only or even the best way to do things but it does demonstrate how to use CLR objects defined using managed C++ from a VB .NET project.

I hope this helps you. Good luck.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.