locked
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

  • 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
  • Which line of code causes you error? What error you got?

    chanmm


    chanmm
    Monday, August 8, 2011 4:09 AM
  • The MarshalDirectiveException is thrown by the marshaler when it encounters a MarshalAsAttribute it does not support.

    So, just use a vaild dlllocation and Entrypoint of method.


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, August 9, 2011 3:28 AM