Dziękuję Wam bardzo za tak wyczerpujące posty : ))
Naprawdę bardzo mi pomogły ;)
Prosty przykładzik śmiga !
Ale teraz jak przeszłam do tego konkretnego kodu ponownie pojawił mi się problem z message :
**An unhandled exception of type 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in WrapperLandmark4.exe
Additional information: Nie można zorganizować 'return value': Nieprawidłowa kombinacja typw zarządzanych/niezarządzanych.**
Jeśli to możliwe jak mógłby ktoś look - nąć na to eksperckim okiem bardzo proszę ?
Będę wdzięczna za jakieś uwagi ;)
W c# 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);** // tutaj ???
Marshal.Copy(pWynik, wynik, 0, 16);
for (int i = 0; i < 16; i++)
{
MessageBox.Show(wynik[i].ToString());
}
Marshal.FreeHGlobal(pWynik);
}
}
}
C# 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);
}
}
Natomiast w 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;
/////////////////////////////////////////////////////////////////
// WYNIK
//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);** // tu wynik ... będzie tablica 16 doubli
}
}
t->Delete();
}
}
}