none
Problem wrapper c++ -> C#. Problem with call method in C# RRS feed

  • Question

  • Hello, I'm beginner in programming . I have to do a wrapper c++ to c#. I have a problem with call a method(form1) in C#. When I 'm starting with build . It 's ok - good.
    
    But When I 'm going to start with debuging . It doesn't compile good. I reveived a message :An unhandled exception of type 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in WrapperLandmark4.exe
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace WrapperLandmark4
    {
      internal static class UnsafeNativeMethods
      {
        const string dllLocation = "D:\\WrapperIGSTK4\\WrapperLandmark4\\WrapperLandmark4\\LandmarkDLL.dll";
    
    
        [DllImport(dllLocation)]
        public static extern double[] Rejestracja(double[] dane, IntPtr pWynik);
        
      }
    }
    

    Hello,

    I'm beginner in programming . 

    I have to do a wrapper c++ to c# .

    I have a problem with call method in C#.

    could someone help me please ? 

    I would appreciate for any help  ;)

    I attach my code :

    Form1.cs

    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 WrapperLandmark4
    {
      public partial class Form1 : Form
      {
        public Form1()
        {
          InitializeComponent();
          Run();
        }
    
    
        public static void Run()
        {
          double[] dane = new double[30];
    
          #region Dane
          dane[0] = 2.3;
          dane[1] = 2.4;
          dane[2] = 4.5;
          dane[3] = 5.5;
          dane[4] = 5.5;
          dane[5] = 6.7;
          dane[6] = 5.6;
          dane[7] = 4.5;
          dane[8] = 5.5;
          dane[9] = 4.4;
          dane[10] = 2.3;
          dane[11] = 2.3;
          dane[12] = 4.5;
          dane[13] = 5.5;
          dane[14] = 5.5;
          dane[15] = 6.7;
          dane[16] = 2.4;
          dane[17] = 4.5;
          dane[18] = 5.5;
          dane[19] = 5.5;
          dane[20] = 6.7;
          dane[21] = 5.6;
          dane[22] = 4.5;
          dane[23] = 5.5;
          dane[24] = 4.4;
          dane[25] = 2.3;
          dane[26] = 2.3;
          dane[27] = 4.5;
          dane[28] = 5.5;
          dane[29] = 5.5;
          #endregion Dane
    
          double[] wynik = new double[16];
          IntPtr pWynik = Marshal.AllocHGlobal(16 * 8);
          UnsafeNativeMethods.Rejestracja(dane, pWynik); // Problem here ??
          Marshal.Copy(pWynik, wynik, 0, 16);
          
    
    
          for (int i = 0; i < 16; i++)
          {
            MessageBox.Show(wynik[i].ToString());
          }
    
          Marshal.FreeHGlobal(pWynik);
        }
      }
    }
    
    

    Class1.cs 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace WrapperLandmark4
    {
      internal static class UnsafeNativeMethods
      {
        const string dllLocation = "D:\\WrapperIGSTK4\\WrapperLandmark4\\WrapperLandmark4\\LandmarkDLL.dll";
    
    
        [DllImport(dllLocation)]
        public static extern double[] Rejestracja(double[] dane, IntPtr pWynik);
        
      }
    }
    

    In C++ :

    extern "C"
    {
    
    	
     __declspec(dllexport) void __stdcall Rejestracja(double tab[30], double *pReturn)
    	 {
    
    igstk::RealTimeClock::Initialize();
    
    
    // BeginCodeSnippet
     typedef igstk::Object::LoggerType       LoggerType;
     typedef itk::StdStreamLogOutput        LogOutputType;
      
     typedef igstk::Landmark3DRegistration
                  Landmark3DRegistrationType;
     typedef igstk::Landmark3DRegistration::LandmarkPointContainerType
                  LandmarkPointContainerType;
     typedef igstk::Landmark3DRegistration::LandmarkImagePointType 
                  LandmarkImagePointType;
     typedef igstk::Landmark3DRegistration::LandmarkTrackerPointType
                  LandmarkTrackerPointType;
     typedef Landmark3DRegistrationType::TransformType::OutputVectorType 
                  OutputVectorType;
     typedef igstk::Transform TransformType;
    // EndCodeSnippet
    
    
    // BeginLatex
    // 
    // Then, the registration component is instantiated as follows:
    // 
    // EndLatex
    
    // BeginCodeSnippet
     Landmark3DRegistrationType::Pointer landmarkRegister = 
                        Landmark3DRegistrationType::New();
    // EndCodeSnippet
     
    
    // BeginLatex
    // 
    // Next, the landmark containers that hold the landmark image and tracker 
    // coordinates are instantiated:
    //
    // EndLatex
    
    // BeginCodeSnippet
     LandmarkPointContainerType imagePointContainer;
     LandmarkPointContainerType trackerPointContainer;
    // EndCodeSnippet
    
    
     LandmarkImagePointType   imagePoint;
     LandmarkTrackerPointType  trackerPoint;
    
    // BeginLatex
    // 
    // Then, error event callback objects are instantiated and added to the observer
    // list of the registration component, as follows:
    //
    // EndLatex
    
    // BeginCodeSnippet
     Landmark3DRegistrationInvalidRequestCallback::Pointer 
             lrcb = Landmark3DRegistrationInvalidRequestCallback::New();
      
     typedef igstk::InvalidRequestErrorEvent InvalidRequestEvent;
    
     landmarkRegister->AddObserver( InvalidRequestEvent(), lrcb );
    
     Landmark3DRegistrationErrorCallback::Pointer ecb = 
             Landmark3DRegistrationErrorCallback::New();
     typedef igstk::Landmark3DRegistration::TransformComputationFailureEvent 
                               ComputationFailureEvent;
     landmarkRegister->AddObserver( ComputationFailureEvent(), ecb );
    
    // EndCodeSnippet
    
    // BeginLatex
    // 
    // A logger can then be connected to the registration component for 
    // debugging purpose, as follows:
    //
    // EndLatex
    
    
    // BeginCodeSnippet 
     LoggerType::Pointer  logger = LoggerType::New();
     LogOutputType::Pointer logOutput = LogOutputType::New();
     logOutput->SetStream( std::cout );
     logger->AddLogOutput( logOutput );
     logger->SetPriorityLevel( LoggerType::DEBUG );
     landmarkRegister->SetLogger( logger );
    // EndCodeSnippet
      
    
    // BeginLatex
    //
    // Next, landmark points are added to the image and tracker containers. The
    // state machine of this registration component is designed so that the image
    // and tracker coordinates that correspond to each landmark are added
    // consecutively. This scheme prevents the mismatch in landmark correspondence
    // that could occur when all landmarks image coordinates are recorded first and
    // followed by the tracker coordinates. This design choice is consistent with
    // the ``safety by design'' philosophy of IGSTK. The commands are as follows:
    //
    //EndLatex 
    
    // BeginCodeSnippet
     // Add entry
     imagePoint[0] = tab[0];
     imagePoint[1] = tab[1];
     imagePoint[2] = tab[2];
     imagePointContainer.push_back(imagePoint);
     landmarkRegister->RequestAddImageLandmarkPoint(imagePoint);
    
     trackerPoint[0] = tab[3];
     trackerPoint[1] = tab[4];
     trackerPoint[2] = tab[5];
     trackerPointContainer.push_back(trackerPoint);
     landmarkRegister->RequestAddTrackerLandmarkPoint(trackerPoint);
    
     // Add 1st landmark
     imagePoint[0] = tab[6];
     imagePoint[1] = tab[7];
     imagePoint[2] = tab[8];
     imagePointContainer.push_back(imagePoint);
     landmarkRegister->RequestAddImageLandmarkPoint(imagePoint);
      
     trackerPoint[0] = tab[9];
     trackerPoint[1] = tab[10];
     trackerPoint[2] = tab[11];
     trackerPointContainer.push_back(trackerPoint);
     landmarkRegister->RequestAddTrackerLandmarkPoint(trackerPoint);
    
     // Add 2nd landmark
     imagePoint[0] = tab[12];
     imagePoint[1] = tab[13];
     imagePoint[2] = tab[14];
     imagePointContainer.push_back(imagePoint);
     landmarkRegister->RequestAddImageLandmarkPoint(imagePoint);
    
     trackerPoint[0] = tab[15];
     trackerPoint[1] = tab[16];
     trackerPoint[2] = tab[17];
     trackerPointContainer.push_back(trackerPoint);
     landmarkRegister->RequestAddTrackerLandmarkPoint(trackerPoint);
    
     // EndCodeSnippet
    
     // BeginLatex
     // 
     // More landmarks can be added for the transform computation. 
     // 
     // EndLatex
    
     // Add 3n landmark
     imagePoint[0] = tab[18];
     imagePoint[1] = tab[19];
     imagePoint[2] = tab[20];
     imagePointContainer.push_back(imagePoint);
     landmarkRegister->RequestAddImageLandmarkPoint(imagePoint);
    
     trackerPoint[0] = tab[21];
     trackerPoint[1] = tab[22];
     trackerPoint[2] = tab[23];
     trackerPointContainer.push_back(trackerPoint);
     landmarkRegister->RequestAddTrackerLandmarkPoint(trackerPoint);
    
     // Add target
     imagePoint[0] = tab[24];
     imagePoint[1] = tab[25];
     imagePoint[2] = tab[26];
     imagePointContainer.push_back(imagePoint);
     landmarkRegister->RequestAddImageLandmarkPoint(imagePoint);
    
     trackerPoint[0] = tab[27];
     trackerPoint[1] = tab[28];
     trackerPoint[2] = tab[29];
     trackerPointContainer.push_back(trackerPoint);
     landmarkRegister->RequestAddTrackerLandmarkPoint(trackerPoint);
    
     // BeginLatex
     // 
     // After all landmark coordinates are added, the transform computation is 
     // requested as follows:
     // 
     // EndLatex
    
     // Calculate transform
    
     // BeginCodeSnippet
     landmarkRegister->RequestComputeTransform();
     // EndCodeSnippet
       
     typedef itk::VersorRigid3DTransform<double>    VersorRigid3DTransformType;
     typedef VersorRigid3DTransformType::ParametersType ParametersType;
    
    
    
    
     TransformType transform;
     ParametersType   parameters(6);
    
     // BeginLatex
     // 
     // To access the transform parameters, a GetTransform callback is instantiated
     // to observe the transform event, as follows: 
     // 
     // EndLatex
    
     // BeginCodeSnippet
     Landmark3DRegistrationGetTransformCallback::Pointer lrtcb =
      Landmark3DRegistrationGetTransformCallback::New();
    
     landmarkRegister->AddObserver( 
      igstk::CoordinateSystemTransformToEvent(), lrtcb );
     //EndCodeSnippet
    
    
     // BeginLatex
     //
     // To request that the registration component throw an event loaded with 
     // transform parameters, a \code{RequestGetTransform} function is invoked as 
     // follows:
     // 
     // EndLatex
    
     // BeginCodeSnippet
     landmarkRegister->RequestGetTransformFromTrackerToImage();
     std::cout<<" "<<std::endl;
     std::cout << "Transform " << transform << std::endl;
    
    
     //double pReturn[16];
    
    
     if(lrtcb->GetEventReceived()) 
    {
     transform = lrtcb->GetTransform();
     vtkMatrix4x4 * t = vtkMatrix4x4::New();;
     transform.ExportTransform( * t );
    
    for ( int i = 0; i < 3; i++ )
    {
     for ( int j = 0; j < 3; j++ )
      {
       pReturn[4*i+j] = t->GetElement(i,j);
      }
    }
    
    t->Delete();
    
    }
    
    }
    
    	
    	
    
    }
    
    


    Could Someone help me please ?

    I would appreciate for any help.

     

     

    Best,

    wiatrak111@

    • Moved by Leo Liu - MSFT Monday, August 8, 2011 7:46 AM Moved for better support. (From:Visual C# General)
    Sunday, August 7, 2011 9:08 AM

Answers

  • I do not believe you can use a variable (dllLocation) as the path to the dll.  Put a constant string in the [DllImport()] attribute.

    --
    Mike
    • Marked as answer by Paul Zhou Tuesday, August 9, 2011 3:28 AM
    Sunday, August 7, 2011 12:36 PM

All replies