Problem Wrapper C++->C# [UnsafeNativeMethods]

0

Hej ;)

Mam problem z wrapperem do C#.
Jeśli to możliwe czy mógłby ktoś looknąć na poniższy kod :
Będę wdzięczna za jakieś uwagi :
Kod builduje się ok - bez błędów, program wywala się przy debugowaniu

**An unhandled exception of type 'System.EntryPointNotFoundException' occurred in WrapperITK.exe

Additional information: W bibliotece DLL 'ProgramITK.dll' nie można znaleźć punktu wejścia o nazwie 'KonwersjaPliku'.**

Nie wiem czym to może być spowodowane, w parametrze opakowanej metody przekazuje typ string (plik wejściowy i wyjściowy)

Kod w C++ :

 
#include "itkOrientedImage.h"
#include "itkGDCMImageIO.h"
#include "itkGDCMSeriesFileNames.h"
#include "itkImageSeriesReader.h"
#include "itkImageFileWriter.h"
#include "itkCommand.h"
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
using namespace std;

extern "C"
{
	__declspec(dllexport) void __stdcall KonwersjaPliku(std::string plikWE, std::string plikWY)
{



typedef signed short PixelType; 
const unsigned int Dimension = 3; 

typedef itk::Image< PixelType, Dimension > ImageType; 
typedef itk::ImageFileReader< ImageType > ReaderType; 

        
		ReaderType::Pointer reader = ReaderType::New();
		reader->SetFileName(plikWE);
		reader->Update(); 
		std::cout << reader<< std::endl;

       // Zapis jako VTK image file
       typedef itk::ImageFileWriter<ImageType> WriterType;
       WriterType::Pointer writerVTK = WriterType::New();
       writerVTK->SetInput(reader->GetOutput());
       writerVTK->SetFileName(plikWY);
       writerVTK->Update();


}
}

Cod w C# :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace WrapperITK
{

    internal static class UnsafeNativeMethods
    {
        const string dllLocation = "ProgramITK.dll";

        [DllImport(dllLocation)]
        public static extern void KonwersjaPliku(string plikWE, string plikWY);

    }
}
 

Kod w c# Form1 :

 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WrapperITK
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Run();
        }

        public static void Run()
        {
            string plikDCM = "plikDCM.dcm";
            string plikVTK = "plikVTK.vtk";
            UnsafeNativeMethods.KonwersjaPliku(plikDCM, plikVTK);  // tutaj wywala mi się 
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

      
    }
}

Będę wdzięczna za każdą pomoc ;)

1

Łączysz deklarację z ciałem funkcji. To błąd. Tu masz poprawnie:

extern "C"
{
        __declspec(dllexport) void __stdcall KonwersjaPliku(std::string plikWE, std::string plikWY);
}

extern void __stdcall KonwersjaPliku(std::string plikWE, std::string plikWY)
{
 
 
 
typedef signed short PixelType; 
const unsigned int Dimension = 3; 
 
typedef itk::Image< PixelType, Dimension > ImageType; 
typedef itk::ImageFileReader< ImageType > ReaderType; 
 
 
                ReaderType::Pointer reader = ReaderType::New();
                reader->SetFileName(plikWE);
                reader->Update(); 
                std::cout << reader<< std::endl;
 
       // Zapis jako VTK image file
       typedef itk::ImageFileWriter<ImageType> WriterType;
       WriterType::Pointer writerVTK = WriterType::New();
       writerVTK->SetInput(reader->GetOutput());
       writerVTK->SetFileName(plikWY);
       writerVTK->Update();
 
 
}

albo też możesz tak:

extern "C" __declspec(dllexport) void __stdcall KonwersjaPliku(std::string plikWE, std::string plikWY)
{
 
 
 
typedef signed short PixelType; 
const unsigned int Dimension = 3; 
 
typedef itk::Image< PixelType, Dimension > ImageType; 
typedef itk::ImageFileReader< ImageType > ReaderType; 
 
 
                ReaderType::Pointer reader = ReaderType::New();
                reader->SetFileName(plikWE);
                reader->Update(); 
                std::cout << reader<< std::endl;
 
       // Zapis jako VTK image file
       typedef itk::ImageFileWriter<ImageType> WriterType;
       WriterType::Pointer writerVTK = WriterType::New();
       writerVTK->SetInput(reader->GetOutput());
       writerVTK->SetFileName(plikWY);
       writerVTK->Update();
 
 
}

Daj:
[DllImport(dllLocation), EntryPoint="KonwersjaPliku"]
http://www.dotnetperls.com/dllimport

Jak to nie zadziała to dodaj bibliotekę za pomocą Add Reference i using.

Ogólnie to nic z tego nie sprawdzałem, więc sama kombinuj ;D

0

Nie tak na pewno nie może być :

 [DllImport(dllLocation), EntryPoint="KonwersjaPliku"]

Nie wiem czy nie jest coś źle z parametrami ?
Choć w opakowanej metodzie przekazuje parametry typu string. W c++ i w c# jest string .. ale ??

2

Nie możesz przekazywać std::string w funkcji która ma być widoczna pod C#.
Prawidłowo po stronie C# powinno być string, a po stronie C const char*.

czyli:

extern bla bla bla KonwersjaPliku(const char *plikWE, const char *plikWY)
[DllImport(dllLocation)]
public static extern void KonwersjaPliku(string plikWE, string plikWY);
0

Dzięki wielkie za good advice ;)
Też myślałam ze coś z tym typem będzie nieprawidłowo ;/
Ale dalej to nie idzie ...

An unhandled exception of type 'System.EntryPointNotFoundException' occurred in WrapperITK.exe

Additional information: W bibliotece DLL 'ProgramITK.dll' nie można znaleźć punktu wejścia o nazwie 'KonwersjaPliku'.

Nie wiem czy może jeszcze jakaś konwersja w C# jest potrzeba ?

Dokonałam zmian w kodzie c++ :

#include "itkOrientedImage.h"
#include "itkGDCMImageIO.h"
#include "itkGDCMSeriesFileNames.h"
#include "itkImageSeriesReader.h"
#include "itkImageFileWriter.h"

#include "itkCommand.h"
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
using namespace std;

extern "C"
{
	__declspec(dllexport) void __stdcall KonwersjaPliku(const char* plikWE,const char * plikWY)
{

  std::string  x1, x2;
  x1=plikWE;
  x2=plikWY;
    typedef signed short PixelType; 
    const unsigned int Dimension = 3; 
    typedef itk::Image< PixelType, Dimension > ImageType; 
    typedef itk::ImageFileReader< ImageType > ReaderType; 

    // Wczytanie Dicomu wolumetrycznego
	ReaderType::Pointer reader = ReaderType::New();
	reader->SetFileName(x1);
	reader->Update(); 
	std::cout << reader<< std::endl;

   // Zapis jako VTK image file
   typedef itk::ImageFileWriter<ImageType> WriterType;
   WriterType::Pointer writerVTK = WriterType::New();
   writerVTK->SetInput(reader->GetOutput());
   writerVTK->SetFileName(x2);
   writerVTK->Update();


}
}

W c# w klasie UnsafeNativeMethods:

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace WrapperITK
{

    internal static class UnsafeNativeMethods
    {
        const string dllLocation = "ProgramITK.dll";

       [DllImport(dllLocation)]
       public static extern void KonwersjaPliku(string plikDCM, string plikVTK);

    }
}


 

w C# :

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WrapperITK
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Run();
        }

        public static void Run()
        {
            string plikDCM = "plikDCM.dcm";
            string plikVTK = "plikVTK.vtk";
            UnsafeNativeMethods.KonwersjaPliku(plikDCM, plikVTK);
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

      
    }
}

2

Additional information: W bibliotece DLL 'ProgramITK.dll' nie można znaleźć punktu wejścia o nazwie 'KonwersjaPliku'.
problem jest w DLL-ce (funkcja nie jest eksportowana).
Spróbuj to extern "C" zrobić tak jak maszynaz napisał.

0

Spoko dzięki wielkie ...
też w sumie miałam tak opakowaną metodę ;)
Diabeł tkwi w szczegółach :

W C# dodałam tak :

 unsafe public static extern void KonwersjaPliku(string plikDCM, string plikVTK);

i we właściwościach projektu odznaczyłam allow unmanaged code .
Jak na razie działa goood !
Tylko jeszcze musze przetestować na innej maszynie .

Dzięki Wielkie za pomoc ;)
Bardzo dziękuje !

0

i we właściwościach projektu odznaczyłam allow unmanaged code .
he? którego projektu? to nie powinno mieć znaczenia.

chyba że chodzi „allow unsafe code”. to też bez znaczenia. to nie jest funkcja wymagająca unsafe.

0

Po to unsafe tutaj? extern "C" musi być bo inaczej wyeksporuje krzaki zamiast KonwersjaPliku (manglowanie nazw) i tylko kompilator, w którym skompilowano dll będzie w stanie to "zrozumieć". Ot taki fajny ficzer made by MS.

1 użytkowników online, w tym zalogowanych: 0, gości: 1