Trouble integrating C++ DLL into C# program

I know this is a C++ website, but the stack overflow community likes to berate those who ask questions at a beginners level.

I wrote the guts of a program in C++ and "wrapped" it into a DLL file. I added it as a reference, called the correct namespace, it shows up in drop-down boxes when calling the function, but I keep getting errors that I Don't understand.

This is the C++ header file:

<string>
using std::string;

#include "C:\Users\Ryan\Documents\Visual Studio 2010\Projects\Crow Bar Sound Functions\Crow Bar Sound Functions\SPlay.h"
#include "C:\Users\Ryan\Documents\Visual Studio 2010\Projects\Crow Bar Sound Functions\Crow Bar Sound Functions\SPlay.cpp"


using namespace System;

namespace CBSoundsDll {

public ref class CrowBarSoundsDLL
{
public:
CrowBarSoundsDLL();

void loadSoundFile(string fileName);
void loadMusicFile(string fileName);
void playBackPlay();
void playBackStop();
void playBackPause();
void playBackVolumeUp();
void playBackVolumeDown();
void playBackSetRepeat();
void playBackNoRepeat();

private:

SPlay *cbSoundFuncs;

// TODO: Add your methods for this class here.
};
}


This is the CPP file:

#include "stdafx.h"

#include "CBSoundsDll.h"

#include "C:\Users\Ryan\Documents\Visual Studio 2010\Projects\Crow Bar Sound Functions\Crow Bar Sound Functions\SPlay.h"
#include "C:\Users\Ryan\Documents\Visual Studio 2010\Projects\Crow Bar Sound Functions\Crow Bar Sound Functions\SPlay.cpp"

#include <string>
using std::string;

CBSoundsDll::CrowBarSoundsDLL::CrowBarSoundsDLL()
{
cbSoundFuncs = new SPlay();
}

void CBSoundsDll::CrowBarSoundsDLL::loadSoundFile(string fileName) {


sf::SoundBuffer loadSound;
sf::Sound playSound;

if(fileName == "") {
fileName = "C:\\Windows\\Media\\Windows Logon.wav";
MessageBox(NULL, TEXT("No specified File Name!"), TEXT("Load Failed"), MB_OK | MB_ICONERROR);
}
else {
if(!loadSound.loadFromFile(fileName))
{
MessageBox(NULL, TEXT("Unable to load sound file!"), TEXT("Load Failed"), MB_OK | MB_ICONERROR);
}
}

playSound.setBuffer(loadSound);
playSound.play();
}

void CBSoundsDll::CrowBarSoundsDLL::loadMusicFile(string fileName) {

sf::SoundBuffer loadSound;
sf::Sound alertSound;

if(fileName == "") {

loadSound.loadFromFile("C:\\Windows\\Media\\Windows Logon.wav");

alertSound.setBuffer(loadSound);
alertSound.play();

MessageBox(NULL, TEXT("No specified file name!"), TEXT("Load Failed"), MB_OK);
}
else {
if(!playMusic.openFromFile(fileName))
{
MessageBox(NULL, TEXT("Unable to load music file!"), TEXT("Load Failed"), MB_OK | MB_ICONERROR);
}
else {
playMusic.play();
}

}
}

void CBSoundsDll::CrowBarSoundsDLL::playBackPause() {
playMusic.pause();
}
void CBSoundsDll::CrowBarSoundsDLL::playBackStop() {
playMusic.stop();
}
void CBSoundsDll::CrowBarSoundsDLL::playBackPlay() {
playMusic.play();
}
void CBSoundsDll::CrowBarSoundsDLL::playBackVolumeUp() {
pbVolume += 1;
playMusic.setVolume(pbVolume);
}
void CBSoundsDll::CrowBarSoundsDLL::playBackVolumeDown() {
pbVolume -= 1;
playMusic.setVolume(pbVolume);
}
void CBSoundsDll::CrowBarSoundsDLL::playBackSetRepeat() {
playMusic.setLoop(true);
}
void CBSoundsDll::CrowBarSoundsDLL::playBackNoRepeat() {
playMusic.setLoop(false);
}



This is the XAML.CS file in C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using CBSoundsDll;

namespace WpfApplication4
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
CrowBarSoundsDLL CrowbarAudio = new CrowBarSoundsDLL();

public MainWindow()
{
InitializeComponent();
}

private void Button_Click(object sender, RoutedEventArgs e)
{
if (RadioButton1.IsChecked == true)
{
MessageBox.Show("Hello");
CrowbarAudio.loadSoundFile("C:\\Windows\\Media\\Windows Logon.wav");
}
else
{
RadioButton2.IsChecked = true;
MessageBox.Show("Goodbye");

}

}

private void RadioButton_Checked(object sender, RoutedEventArgs e)
{

}

private void RadioButton_Checked_1(object sender, RoutedEventArgs e)
{

}
}
}


***CrowbarAudio.loadSoundFile("") is the line that's causing the errors below***

The errors/warnings:

1. Warning There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "CBSoundsDll", "x86". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project. WpfApplication4

2. Error 'loadSoundFile' is not supported by the language

3. Error The best overloaded method match for 'CBSoundsDll.CrowBarSoundsDLL.loadSoundFile(std.basic_string<char,std.char_traits<char>,std::allocator<char> >*)' has some invalid arguments

4.Error 4 Argument 1: cannot convert from 'string' to 'std.basic_string<char,std.char_traits<char>,std::allocator<char> >*'


Also, there was a message saying there was a problem loading a file or assemly (my dll file) because one of the dependencies could not be found. I'm assuming I didn't add sfml dll's though.
Freddie thanks! It does help a little, I can get the DLL imported, and the code recognizes my functions, but I'm still having trouble. I've narrowed the problem down to the face that i'm trying to pass a C# string into a native code function that takes a C++. I"ve found the problem with that is that those two strings aren't interop friendly, i'm looking into pinvoke now, but i'm having trouble finding examples that show how to pass a C# to a native code function.

Basically my problem lies in trying to pass a C# string to a C++ function in a native wrapped DLL

More research for today!

Thanks for the help man I appreciate it
Last edited on
Strings are almost always the problem when attempting to interoperate between different languages. The Win Api strictly uses null terminated character arrays, and those are pretty much the lowest common denominator. Is there a way to pass the address of a null terminated C# string to your C++ Dll? I don't know .NET very well, so I don't know. But that might be something worth trying. Also, I think it might be easier if your C++ dll was using std::wstring instead of std::string. I don't believe .NET is set up to deal with narrow strings, so that's just another hurdle to overcome.
Thanks i'm gonna go ahead and give that a shot. I like c++ and i spent the last year learning it, but GUI programming for it is horrible, so I elected to program the front end in C# and the guts of the program in c++. I'll check out wstring instead of string, thanks again!
Last edited on

...but GUI programming for it is horrible...


Its really not, and I'm sincere in saying that. It is however, a significant paradigm shift.

Basically, there are two completely different ways to go about it. First is the pure Win Api SDK route. That's what I do.

Secondly, there is the class framework route. Although this is perhaps the most popular, I dislike it and don't do it.

The difficulties most folks starting out in C++ have with the Windows Api is failure to realize that they are looking at C based object oriented programming. And yes, its posible to do object oriented programming in C. All the earliest C++ compilers did was convert C++ code to C and compile the C.

The reason I'm against class frameworks is that all they do is add another 'wrapper' layer on top of what is essentially an excellent OOP system 'as is'.

I will admit it takes a lot of work to learn GUI coding in C++, so I guess you have to ask yourself how much time you want to invest in it. There are various resources available on the net of course, and I've even written one of them...

http://www.jose.it-berater.org/smfforum/index.php?topic=3389.0

And the Forger's Win32 Tutorial Series is also well regarded. Good luck with your project though. Sorry I can't help more. I know very little VB.NET and almost no C#.



Don't apologize, you've helped me out quite a bit. I do want to stick with C++ as I've invested a lot of time learning it, but i'm also dead set on win32 programming. It's a paradox I guess but i'm a determined individual. The reason I decided to use C# (which i'm still very new to) is because it was easier to do make interfaces for the Windows API. You've helped me quite a bit and now I know that strings are a large culprit in road blocks with interop programming.
Topic archived. No new replies allowed.