Buenas!
mucha gente esta contactando conmigo para preguntar si la lib sera portada a C#, la respuesta es no pero si se podria realizar un port...
He mirado un poco el tema y se me ha ocurrido hacer una especie de wrapper en C# donde llame a todas las funciones de la libreria.
Y me han surgido unas preguntas:
-se puede exportar clases completas o al menos sus metodos?
-es una locura hacer un wrapper
-existe alguna manera mejor de que la gente que quiera, pueda utilizar la libreria DLL desde C#?
Tambien se aceptan voluntarios eh? jeje
Espero vuestras respuestas que yo de C# no estoy nada puesto... gracias!
en este ejemplo indican como usar dlls del api win32, esto me imagino que te ayudara en parte ya que solo he visto la manera de importar funciones globales, la unica solucion es lo que hablaban en otro hilo, usar algun tipo de clase proxy, yo muchas veces cuando estoy programando en c++ pienso si no es mejor hacerlo en c y luego hacer por encima de eso una clase :(
http://www.codeproject.com/csharp/cscapturescreen1.asp
yo tengo un wrapper de Newton con C# 2.0 y es facilísimo.
Te creas una clase con lo que tu quieras y listo, no necesitas proxy ni nada de eso... :P
podias poner algun ejemplo pequeño y no solo decir que lo has hecho ;)
Lo que pasa es que Newton está programada en C. En C++ me imagino que sería más complicado.
Saludos.
Efectivamente, la lib esta en C++. Si se tratara de C puro y duro creo que solo hay una forma de hacerlo...seria encapsularlo todo en una clase y wrapear todas las llamadas, como ha hecho haddd con newton.
El problema esta con clases en C++... alguien puede arrojar luz sobre este tema?
Yo siempre que he leído sobre este tema, aconsejan programar el wrapper en managed C++. Pero sería interesante saber si existe una forma de hacerlo directamente desde C# (que me temo que va a ser que no :lol:)...
Saludos.
Cita de: BeRSeRKeRYo siempre que he leído sobre este tema, aconsejan programar el wrapper en managed C++. Pero sería interesante saber si existe una forma de hacerlo directamente desde C# (que me temo que va a ser que no :lol:)...
Saludos.
Vamos, que por lo que parece, no es tan trivial usar desde C# una DLL escrita en C++ no?
Bueno, pues si alguien anade algo o quiere intentar algo que lo diga... que yo por el momento estoy un poco saturado haciendo mil cosillas. Si descubriera algo nuevo en relacion a esto, lo posteare por aqui....
saludos
Buscando por la Web alguna forma de crear el wrapper me encontre con esto:
SWIGTu que opinas TheAzazel, podria usarse??
Te sirve??
Citarpodias poner algun ejemplo pequeño y no solo decir que lo has hecho
En la web de Newton puse todo el código...
#region Using directives
using System;
using System.Collections;
using System.Text;
using System.Runtime.InteropServices; // DllImport
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using HadddEngine.Scene;
#endregion
/*
ATENCION
Debo crear a veces 2 métodos diferentes, porque al esperar un float *, es posible
que se le pase un null desde la aplicación.
Si paso un null esperando como un parámetro ref Matrix, me da un error
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateBox")]
public static extern int CreateBox(int newtonWorld, float dx, float dy, float dz, ref Matrix offsetMatrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateBox")]
public static extern int CreateBox(int newtonWorld, float dx, float dy, float dz, float[] matrix);
*/
namespace HadddEngine.Physics
{
#region structs
public struct NewtonHingeSliderUpdateDesc
{
public float accel;
public float minFriction;
public float maxFriction;
public float timestep;
};
#endregion
#region Delegates
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate void SetTransformCB(int body, ref Matrix matrix);
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate void SetForceAndTorqueCB(int body);
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate void CreateTreeCollision(int bodyWithTreeCollision,int body,float[] vertex,int vertexstrideInBytes, int indexCount, int[] indexArray);
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate int MaterialSetCollisionBegin(int material, int body0, int body1);
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate int MaterialSetCollisionProcess(int material, int contact);
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate void MaterialSetCollisionEnd(int material);
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate void BodyLeaveWorld(int body);
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate void BodyIterator(int body);
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate float WorldRayCastCB(int body, ref Vector3 normal, int collisionID, [MarshalAs(UnmanagedType.IUnknown)] Object userData, float intersetParam);
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate void CollisionIteratorCB(int body, int vertexCount, IntPtr faceVert, int ID);
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate int HingeJointCB(int joint, ref NewtonHingeSliderUpdateDesc desc);
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate int SliderJointCB(int joint, ref NewtonHingeSliderUpdateDesc desc);
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate int UniversalJointCB(int joint, IntPtr desc);
#endregion
#region Wrapper
public class NewtonWrapper
{
#region WorldInterface
[DllImport("Newton.Dll",EntryPoint="NewtonCreate")]public static extern int Create(int a, int b);
[DllImport("Newton.Dll", EntryPoint = "NewtonGetGlobalScale")]public static extern float GetGlobalScale(int newtonWorld);
[DllImport("Newton.Dll", EntryPoint = "NewtonSetSolverModel")]public static extern void SetSolverModel(int a, int b);
[DllImport("Newton.Dll", EntryPoint = "NewtonSetFrictionModel")]public static extern void SetFrictionModel(int a, int b);
[DllImport("Newton.Dll", EntryPoint = "NewtonUpdate")]public static extern void Update(int newtonWorld, float timestep);
[DllImport("Newton.Dll", EntryPoint = "NewtonWorldCollide")]public static extern void WorldCollide(int newtonWorld, int maxSize,int collisionA,ref Matrix offsetA,int collisionB,ref Matrix offsetB,float[] contacts,float[] normals,float[] penetration);
[DllImport("Newton.Dll", EntryPoint = "NewtonDestroy")]public static extern void Destroy(int newtonWorld);
[DllImport("Newton.Dll", EntryPoint = "NewtonSetMinimumFrameRate")]public static extern void SetMinimumFrameRate(int newtonWorld, float frameRate);
[DllImport("Newton.Dll", EntryPoint = "NewtonGetTimeStep")]public static extern float GetTimeStep(int newtonWorld);
[DllImport("Newton.Dll", EntryPoint = "NewtonDestroyAllBodies")]public static extern void DestroyAllBodies(int newtonWorld);
[DllImport("Newton.Dll", EntryPoint = "NewtonSetWorldSize")]public static extern void SetWorldSize(int newtonWorld, ref Vector3 min,ref Vector3 max);
[DllImport("Newton.Dll", EntryPoint = "NewtonSetBodyLeaveWorldEvent")]public static extern void SetBodyLeaveWorldEvent(int newtonWorld, BodyLeaveWorld cb);
[DllImport("Newton.Dll", EntryPoint = "NewtonWorldFreezeBody")]public static extern void WorldFreezeBody(int newtonWorld,int body);
[DllImport("Newton.Dll", EntryPoint = "NewtonWorldUnfreezeBody")]public static extern void WorldUnfreezeBody(int newtonWorld, int body);
[DllImport("Newton.Dll", EntryPoint = "NewtonWorldForEachBodyDo")]public static extern void WorldForEachBodyDo(int newtonWorld, BodyIterator cb);
[DllImport("Newton.Dll", EntryPoint = "NewtonGetVersion")]public static extern int GetVersion(int newtonWorld);
[DllImport("Newton.Dll", EntryPoint = "NewtonWorldSetUserData")]public static extern void WorldSetUserData(int bodyPtr, [MarshalAs(UnmanagedType.IUnknown)] Object o);
[DllImport("Newton.Dll", EntryPoint = "NewtonWorldGetUserData")][return: MarshalAs(UnmanagedType.IUnknown)]public static extern Object WorldGetUserData(int bodyPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonWorldRayCast")]
public static extern void WorldRayCast(int newtonWorld, ref Vector3 p0, ref Vector3 p1, WorldRayCastCB cb, [MarshalAs(UnmanagedType.IUnknown)] Object userData);
#endregion
#region GroupID interface
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialGetDefaultGroupID")]public static extern int MaterialGetDefaultGroupID(int newtonWorld);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialCreateGroupID")]public static extern int MaterialCreateGroupID(int newtonWorld);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialDestroyAllGroupID")]
public static extern void MaterialDestroyAllGroupID(int newtonWorld);
#endregion
#region Material setup interface
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialSetDefaultSoftness")]public static extern void MaterialSetDefaultSoftness(int newtonWorld, int id0, int id1, float softnessCoef);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialSetDefaultElasticity")]public static extern void MaterialSetDefaultElasticity(int newtonWorld, int id0, int id1, float elasticCoef);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialSetDefaultCollidable")]public static extern void MaterialSetDefaultCollidable(int newtonWorld, int id0, int id1, int state);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialSetDefaultFriction")]public static extern void MaterialSetDefaultFriction(int newtonWorld, int id0, int id1, float staticFriction,float kineticFriction);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialSetCollisionCallback")]public static extern void MaterialSetCollisionCallback(int newtonWorld, int id0, int id1, [MarshalAs(UnmanagedType.IUnknown)] Object UserData, MaterialSetCollisionBegin cb1, MaterialSetCollisionProcess cb2, MaterialSetCollisionEnd cb3);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialGetUserData ")]
public static extern int MaterialGetUserData(int newtonWorld, int id0, int id1);
#endregion
#region Contact behavior control interface
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialDisableContact")]
public static extern void MaterialDisableContact(int materialHandle);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialGetMaterialPairUserData")]
[return: MarshalAs(UnmanagedType.IUnknown)]
public static extern Object MaterialGetMaterialPairUserData(int materialHandle);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialGetContactFaceAttribute")]
public static extern uint MaterialGetContactFaceAttribute(int materialHandle);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialGetCurrentTimestep")]
public static extern float MaterialGetCurrentTimestep(int materialHandle);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialGetContactNormalSpeed")]
public static extern float MaterialGetContactNormalSpeed(int materialHandle, int contactHandle);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialGetContactTangentSpeed")]
public static extern float MaterialGetContactTangentSpeed(int materialHandle, int contactHandle, int index);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialGetContactPositionAndNormal")]
public static extern void MaterialGetContactPositionAndNormal(int materialHandle, ref Vector3 position, ref Vector3 normal);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialGetContactForce")]
public static extern void MaterialGetContactForce(int materialHandle, ref Vector3 force);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialGetContactTangentDirections")]
public static extern void MaterialGetContactTangentDirections(int materialHandle, ref Vector3 dir0, ref Vector3 dir1);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialGetBodyCollisionID")]
public static extern uint MaterialGetBodyCollisionID(int materialHandle,int body);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialSetContactSoftness")]
public static extern void MaterialSetContactSoftness(int materialHandle, float softness);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialSetContactElasticity")]
public static extern void MaterialSetContactElasticity(int materialHandle, float restitution);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialSetContactFrictionState")]
public static extern void MaterialSetContactFrictionState(int materialHandle, int state,int index);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialSetContactStaticFrictionCoef")]
public static extern void MaterialSetContactStaticFrictionCoef(int materialHandle, float coef, int index);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialSetContactKineticFrictionCoef")]
public static extern void MaterialSetContactKineticFrictionCoef(int materialHandle, float coef, int index);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialSetContactTangentAcceleration")]
public static extern void MaterialSetContactTangentAcceleration(int materialHandle, float accel, int index);
[DllImport("Newton.Dll", EntryPoint = "NewtonMaterialContactRotateTangentDirections")]
public static extern void MaterialContactRotateTangentDirections(int materialHandle, ref Vector3 alignVector);
#endregion
#region Convex collision primitives interface
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateNull")]
public static extern int CreateNull(int newtonWorld, float dx, float dy, float dz, ref Matrix offsetMatrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateBox")]
public static extern int CreateBox(int newtonWorld, float dx, float dy, float dz, ref Matrix offsetMatrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateBox")]
public static extern int CreateBox(int newtonWorld, float dx, float dy, float dz, float[] matrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateSphere")]
public static extern int CreateSphere(int newtonWorld, float rx, float ry, float rz, ref Matrix offsetMatrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateSphere")]
public static extern int CreateSphere(int newtonWorld, float rx, float ry, float rz, float[] matrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateCone")]
public static extern int CreateCone(int newtonWorld, float radius, float height, ref Matrix offsetMatrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateCone")]
public static extern int CreateCone(int newtonWorld, float radius, float height, float[] matrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateCapsule")]
public static extern int CreateCapsule(int newtonWorld, float radius, float height, ref Matrix offsetMatrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateCapsule")]
public static extern int CreateCapsule(int newtonWorld, float radius, float height, float[] matrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateCylinder")]
public static extern int CreateCylinder(int newtonWorld, float radius, float height, ref Matrix offsetMatrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateCylinder")]
public static extern int CreateCylinder(int newtonWorld, float radius, float height, float[] matrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateChamferCylinder")]
public static extern int CreateChamferCylinder(int newtonWorld, float radius, float height, ref Matrix offsetMatrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateChamferCylinder")]
public static extern int CreateChamferCylinder(int newtonWorld, float radius, float height, float[] matrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateConvexHull")]
public static extern int CreateConvexHull(int newtonWorld, int count, float[] vertexCloud, int strideInBytes,ref Matrix offsetMatrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateConvexHull")]
public static extern int CreateConvexHull(int newtonWorld, int count, float[] vertexCloud, int strideInBytes, float[] offsetMatrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateConvexHullModifier")]
public static extern int CreateConvexHullModifier(int newtonWorld, int convexHullCollision);
[DllImport("Newton.Dll", EntryPoint = "NewtonConvexHullModifierGetMatrix ")]
public static extern void ConvexHullModifierGetMatrix(int convexHullCollision, ref Matrix matrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonConvexHullModifierSetMatrix ")]
public static extern void ConvexHullModifierSetMatrix(int convexHullCollision, ref Matrix matrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateCompoundCollision")]
public static extern int CreateCompoundCollision(int newtonWorld, int count, int[] collisionPrimitiveArray);
[DllImport("Newton.Dll", EntryPoint = "NewtonConvexCollisionSetUserID")]
public static extern void ConvexCollisionSetUserID(int newtonWorld, uint id);
[DllImport("Newton.Dll", EntryPoint = "NewtonConvexCollisionGetUserID")]
public static extern uint ConvexCollisionSetUserID(int newtonWorld);
#endregion
#region Complex collision primitives interface
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateTreeCollision")]
public static extern int CreateTreeCollision(int bodyPtr, CreateTreeCollision cb);
[DllImport("Newton.Dll", EntryPoint = "NewtonTreeCollisionBeginBuild")]
public static extern void TreeCollisionBeginBuild(int treeCollision);
[DllImport("Newton.Dll", EntryPoint = "NewtonTreeCollisionAddFace")]
public static extern void TreeCollisionAddFace(int bodyPtr, int vertexCount, float[] vertexPtr, int strideInBytes, int faceAttribute);
[DllImport("Newton.Dll", EntryPoint = "NewtonTreeCollisionEndBuild")]
public static extern void TreeCollisionEndBuild(int treeCollision, int optimize);
[DllImport("Newton.Dll", EntryPoint = "NewtonTreeCollisionGetFaceAtribute")]
public static extern void TreeCollisionGetFaceAtribute(int treeCollision, int[] faceIndexArray);
#endregion
#region Collision miscellaneous interface
[DllImport("Newton.Dll", EntryPoint = "NewtonReleaseCollision")]public static extern void ReleaseCollision(int newtonWorld, int collisionPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonCollisionCalculateAABB")]public static extern void CollisionCalculateAABB(int collisionPtr, ref Matrix offsetMatrix,ref Vector3 min,ref Vector3 max);
[DllImport("Newton.Dll", EntryPoint = "NewtonCollisionRayCast")]
public static extern float CollisionRayCast(int collisionPtr, ref Vector3 p0, ref Vector3 p1,ref Vector3 Normal,int[] attribute);
#endregion
#region Transform utility functions
[DllImport("Newton.Dll", EntryPoint = "NewtonGetEulerAngle")]
public static extern void GetEulerAngle(ref Matrix matrix,ref Vector3 angles);
[DllImport("Newton.Dll", EntryPoint = "NewtonSetEulerAngle")]
public static extern void SetEulerAngle(ref Matrix matrix, ref Vector3 angles);
#endregion
#region Rigid body interface
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateBody")]
public static extern int CreateBody(int newtonWorld, int collisionPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetUserData")]
public static extern void BodySetUserData(int bodyPtr, [MarshalAs(UnmanagedType.IUnknown)] Object o);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetUserData")]
[return: MarshalAs(UnmanagedType.IUnknown)]
public static extern Object BodyGetUserData(int bodyPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetWorld")]
public static extern int BodyGetWorld(int bodyPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetTransformCallback")]
public static extern void BodySetTransformCallback(int bodyPtr, SetTransformCB cb);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetForceAndTorqueCallback")]
public static extern void BodySetForceAndTorqueCallback(int bodyPtr, SetForceAndTorqueCB cb);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetMassMatrix")]
public static extern void BodySetMassMatrix(int bodyPtr, float mass, float Ixx, float Iyy, float Izz);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetMassMatrix")]
public static extern void BodyGetMassMatrix(int bodyPtr, out float mass, out float Ixx, out float Iyy, out float Izz);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetInvMass")]
public static extern void BodyGetInvMass(int bodyPtr, out float mass, out float Ixx, out float Iyy, out float Izz);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetMatrix")]
public static extern void BodySetMatrix(int bodyPtr, ref Matrix matrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetMatrixRecursive")]
public static extern void BodySetMatrixRecursive(int bodyPtr, ref Matrix matrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetMatrix")]
public static extern void BodyGetMatrix(int bodyPtr, ref Matrix matrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetForce")]
public static extern void BodySetForce(int bodyPtr, ref Vector3 force);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyAddForce")]
public static extern void BodyAddForce(int bodyPtr, ref Vector3 force);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetForce")]
public static extern void BodyGetForce(int bodyPtr, ref Vector3 force);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetTorque")]
public static extern void BodySetTorque(int bodyPtr, ref Vector3 torque);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyAddTorque")]
public static extern void BodyAddTorque(int bodyPtr, ref Vector3 torque);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetTorque")]
public static extern void BodyGetTorque(int bodyPtr, ref Vector3 torque);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetTotalVolume")]
public static extern float BodyGetTotalVolume(int bodyPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyAddBuoyancyForce")]
public static extern void BodyAddBuoyancyForce(int bodyPtr,float fluidDensity,float fluidLinearViscosity,float fluidAngularViscosity,float[] gravityVector,int buoyancyPlane);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetCollision")]
public static extern void BodySetCollision(int bodyPtr, int collision);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyCoriolisForcesMode")]
public static extern void BodyCoriolisForcesMode(int bodyPtr, int mode);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetCollision")]
public static extern int BodyGetCollision(int bodyPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetMaterialGroupID")]
public static extern void BodySetMaterialGroupID(int bodyPtr, int materialID);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetMaterialGroupID")]
public static extern int BodyGetMaterialGroupID(int bodyPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetJointRecursiveCollision")]
public static extern void BodySetJointRecursiveCollision(int bodyPtr, int state);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetJointRecursiveCollision")]
public static extern int BodyGetJointRecursiveCollision(int bodyPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetAutoFreeze")]
public static extern void BodySetAutoFreeze(int bodyPtr, int state);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetAutoFreeze")]
public static extern int BodyGetAutoFreeze(int bodyPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetSleepingState")]
public static extern int NewtonBodyGetSleepingState(int bodyPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetFreezeTreshold")]
public static extern void BodySetFreezeTreshold(int bodyPtr, float freezeSpeedMag2, float freezeOmegaMag2, int framesCount);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetFreezeTreshold")]
public static extern void BodyGetFreezeTreshold(int bodyPtr, ref float freezeSpeedMag2, ref float freezeOmegaMag2);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetAABB")]
public static extern void BodyGetAABB(int bodyPtr, ref Vector3 min,ref Vector3 max);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetVelocity")]
public static extern void BodySetVelocity(int bodyPtr, ref Vector3 velocity);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetVelocity")]
public static extern void BodyGetVelocity(int bodyPtr, ref Vector3 velocity);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetOmega")]
public static extern void BodySetOmega(int bodyPtr, ref Vector3 omega);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetOmega")]
public static extern void BodyGetOmega(int bodyPtr, ref Vector3 omega);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetLinearDamping")]
public static extern void BodySetLinearDamping(int bodyPtr, float linearDamp);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetLinearDamping")]
public static extern float BodyGetLinearDamping(int bodyPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodySetAngularDamping")]
public static extern void BodySetAngularDamping(int bodyPtr, ref Vector3 angularDamp);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyGetAngularDamping")]
public static extern void BodyGetAngularDamping(int bodyPtr, ref Vector3 angularDamp);
[DllImport("Newton.Dll", EntryPoint = "NewtonBodyForEachPolygonDo")]
public static extern void BodyForEachPolygonDo(int bodyPtr, CollisionIteratorCB cb);
[DllImport("Newton.Dll", EntryPoint = "NewtonAddBodyImpulse")]
public static extern void AddBodyImpulse(int bodyPtr, ref Vector3 pointDeltaVeloc, ref Vector3 pointPosit);
#endregion
#region Ball and Socket joint interface
[DllImport("Newton.Dll", EntryPoint = "NewtonConstraintCreateBall")]
public static extern int ConstraintCreateBall(int world, ref Vector3 pivotPoint, int childBody, int parentBody);
[DllImport("Newton.Dll", EntryPoint = "NewtonBallSetConeLimits")]
public static extern void BallSetConeLimits(int bodyPtr, ref Vector3 pin, float maxConeAngle, float maxTwistAngle);
[DllImport("Newton.Dll", EntryPoint = "NewtonBallGetJointAngle")]
public static extern void BallGetJointAngle(int jointPtr, ref Vector3 angle);
[DllImport("Newton.Dll", EntryPoint = "NewtonBallGetJointOmega")]
public static extern void BallGetJointOmega(int jointPtr, ref Vector3 omega);
[DllImport("Newton.Dll", EntryPoint = "NewtonBallGetJointForce")]
public static extern void BallGetJointForce(int jointPtr, ref Vector3 force);
#endregion
#region Hinge joint interface
[DllImport("Newton.Dll", EntryPoint = "NewtonConstraintCreateHinge")]
public static extern int ConstraintCreateHinge(int bodyPtr, ref Vector3 pivotPoint, ref Vector3 pinDir, int childBody, int parentBody);
[DllImport("Newton.Dll", EntryPoint = "NewtonHingeGetJointAngle")]
public static extern float HingeGetJointAngle(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonHingeGetJointOmega")]
public static extern float HingeGetJointOmega(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonHingleGetJointForce")]
public static extern void HingleGetJointForce(int jointPtr, ref Vector3 force);
[DllImport("Newton.Dll", EntryPoint = "NewtonHingeCalculateStopAlpha")]
public static extern float HingeCalculateStopAlpha(int jointPtr, ref NewtonHingeSliderUpdateDesc desc,float angleLimit);
[DllImport("Newton.Dll", EntryPoint = "NewtonHingeSetUserCallback")]
public static extern void HingeSetUserCallback(int jointPtr, HingeJointCB callback);
#endregion
#region Slider joint interface
[DllImport("Newton.Dll", EntryPoint = "NewtonConstraintCreateSlider")]
public static extern int ConstraintCreateSlider(int bodyPtr, ref Vector3 pivotPoint, ref Vector3 pinDir, int childBody, int parentBody);
[DllImport("Newton.Dll", EntryPoint = "NewtonSliderGetJointPosit")]
public static extern float SliderGetJointPosit(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonSliderGetJointVeloc")]
public static extern float SliderGetJointVeloc(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonSliderGetJointForce")]
public static extern void SliderGetJointForce(int jointPtr, ref Vector3 force);
[DllImport("Newton.Dll", EntryPoint = "NewtonSliderSetUserCallback")]
public static extern void SliderSetUserCallback(int jointPtr, SliderJointCB callback);
[DllImport("Newton.Dll", EntryPoint = "NewtonSliderCalculateStopAccel")]
public static extern float SliderCalculateStopAccel(int jointPtr, ref NewtonHingeSliderUpdateDesc desc, float angleLimit);
#endregion
#region Corkscrew joint interface
[DllImport("Newton.Dll", EntryPoint = "NewtonConstraintCreateCorkscrew")]
public static extern void ConstraintCreateCorkscrew(int bodyPtr, float[] pivotPoint, float[] pinDir, int childBody, int parentBody);
[DllImport("Newton.Dll", EntryPoint = "NewtonCorkscrewGetJointPosit ")]
public static extern float CorkscrewGetJointPosit(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonCorkscrewGetJointVeloc")]
public static extern float CorkscrewGetJointVeloc(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonCorkscrewGetJointAngle ")]
public static extern float CorkscrewGetJointAngle(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonCorkscrewGetJointOmega")]
public static extern float NewtonCorkscrewGetJointOmega(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonCorkscrewGetJointForce")]
public static extern void CorkscrewGetJointForce(int jointPtr, ref Vector3 force);
#endregion
#region Universal joint interface
[DllImport("Newton.Dll", EntryPoint = "NewtonConstraintCreateUniversal")]
public static extern int ConstraintCreateUniversal(int nWorld, ref Vector3 pivotPoint, ref Vector3 pinDir0, ref Vector3 pinDir1, int childBody, int parentBody);
[DllImport("Newton.Dll", EntryPoint = "NewtonUniversalGetJointAngle0")]
public static extern float UniversalGetJointAngle0(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonUniversalGetJointAngle1")]
public static extern float UniversalGetJointAngle1(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonUniversalGetJointOmega0")]
public static extern float UniversalGetJointOmega0(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonUniversalGetJointOmega1")]
public static extern float UniversalGetJointOmega1(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonUniversalGetJointForce")]
public static extern void UniversalGetJointForce(int jointPtr, ref Vector3 force);
[DllImport("Newton.Dll", EntryPoint = "NewtonUniversalSetUserCallback")]
public static extern void UniversalSetUserCallback(int jointPtr, UniversalJointCB callback);
[DllImport("Newton.Dll", EntryPoint = "NewtonUniversalCalculateStopAlpha0")]
public static extern float UniversalCalculateStopAlpha0(int jointPtr, IntPtr desc, float angleLimit);
[DllImport("Newton.Dll", EntryPoint = "NewtonUniversalCalculateStopAlpha1")]
public static extern float UniversalCalculateStopAlpha1(int jointPtr, IntPtr desc, float angleLimit);
#endregion
#region UpVector joint interface
[DllImport("Newton.Dll", EntryPoint = "NewtonConstraintCreateUpVector")]
public static extern int ConstraintCreateUpVector(int nWorld, ref Vector3 pinDir, int body);
[DllImport("Newton.Dll", EntryPoint = "NewtonUpVectorGetPin")]
public static extern void UpVectorGetPin(int jointPtr, ref Vector3 pin);
[DllImport("Newton.Dll", EntryPoint = "NewtonUpVectorSetPin")]
public static extern void UpVectorSetPin(int jointPtr, ref Vector3 pin);
#endregion
#region Joint common functions
[DllImport("Newton.Dll", EntryPoint = "NewtonJointSetUserData")]
public static extern void JointSetUserData(int jointPtr, [MarshalAs(UnmanagedType.IUnknown)] Object o);
[DllImport("Newton.Dll", EntryPoint = "NewtonJointGetUserData")]
[return: MarshalAs(UnmanagedType.IUnknown)]
public static extern Object JointGetUserData(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonJointSetCollisionState")]
public static extern void JointSetCollisionState(int jointPtr, int state);
[DllImport("Newton.Dll", EntryPoint = "NewtonJointGetCollisionState")]
public static extern int JointGetCollisionState(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonJointSetStiffness")]
public static extern void JointSetStiffness(int jointPtr, float stifness);
[DllImport("Newton.Dll", EntryPoint = "NewtonJointGetStiffness")]
public static extern float JointGetStiffness(int jointPtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonDestroyJoint")]
public static extern void DestroyJoint(int nWorld,int jointPtr);
#endregion
#region Rag doll joint container Interface
[DllImport("Newton.Dll", EntryPoint = "NewtonCreateRagDoll")]
public static extern int CreateRagDoll(int nWorld);
[DllImport("Newton.Dll", EntryPoint = "NewtonDestroyRagDoll")]
public static extern void DestroyRagDoll(int nWorld, int ragDoll);
[DllImport("Newton.Dll", EntryPoint = "NewtonRagDollBegin")]
public static extern void RagDollBegin(int ragDoll);
[DllImport("Newton.Dll", EntryPoint = "NewtonRagDollEnd")]
public static extern void RagDollEnd(int ragDoll);
[DllImport("Newton.Dll", EntryPoint = "NewtonRagDollAddBone")]
public static extern void NewtonRagDollAddBone(int ragDoll, int parentBone, [MarshalAs(UnmanagedType.IUnknown)] Object o,float mass,ref Matrix matrix,int boneCollision,ref Vector3 size);
[DllImport("Newton.Dll", EntryPoint = "NewtonRagDollBoneGetUserData")]
[return: MarshalAs(UnmanagedType.IUnknown)]
public static extern Object RagDollBoneGetUserData(int ragdollBonePtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonRagDollBoneSetID")]
public static extern void RagDollBoneSetID(int ragdollBonePtr, int id);
[DllImport("Newton.Dll", EntryPoint = "NewtonRagDollFindBone")]
public static extern int RagDollFindBone(int ragdollBonePtr, int id);
[DllImport("Newton.Dll", EntryPoint = "NewtonRagDollBoneGetBody")]
public static extern int RagDollBoneGetBody(int ragdollBonePtr);
[DllImport("Newton.Dll", EntryPoint = "NewtonRagDollBoneSetLimits")]
public static extern void RagDollBoneSetLimits(int ragdollBonePtr,ref Vector3 coneDir,float minConeAngle,float maxConeAngle,float maxTwistAngle,float[] lateralConeDir,float negativeBilateralConeAngle,float positiveBilateralConeAngle);
[DllImport("Newton.Dll", EntryPoint = "NewtonRagDollBoneGetLocalMatrix")]
public static extern void RagDollBoneGetLocalMatrix(int ragdollBonePtr, ref Matrix matrix);
[DllImport("Newton.Dll", EntryPoint = "NewtonRagDollBoneGetGlobalMatrix")]
public static extern void RagDollBoneGetGlobalMatrix(int ragdollBonePtr, ref Matrix matrix);
#endregion
}
#endregion
}
Hola,
si existe Qt# y esas cosas debería poder hacerse un wrapper de C++ (no creo que hayan reescrito todo en C#), voy a investigar a ver si veo algo... Un saludo!
Vicente
En el curro hacemos lo que dice Haddd. Tenemos unas classes en C++ para cosas de DirectShow y una capa por encima con C#.
Pero lo que hace haddd con el newton... no es hacer un wrapper de C?
No conozco el newton y lo mismo no es C que es C++(cuando hablamos de C++ se sobreentiende que nos referimos al uso de clases).
Vicent, y como lo haceis en el curro entonces? utilizais desde C# clases en una DLL escrita en C#?
Gezequiel, estoy mirando esa web... aunque lo mejor(si se puede) seria no utilizar ningun otro codigo de terceros... lo suyo seria como lo tiene haddd, directamente un wrapper en C# y fuera...
A ver si entre todos localizamos algo y muchas gracias por contestar!
Saludos
A ver si te puedo ayudar en algo, aunque yo no he hecho esta parte de código y no sé exactamente como va.
Nosotros tenemos, por ejemplo, una dll programada en C++ y DirectShow para hacer un render de un vídeo. Aqui te pasteo un trozo del fichero exports.cpp.
BOOL DLL_CALLCONV RunClient(int IdClient)
{
bool res;
if(IdClient >= MAX_CLIENT) return false;
if(pClient[IdClient]==NULL) return false;
res = pClient[IdClient]->Run();
return res;
}
La aplicación que utiliza esta dll es una aplicación hecha en C#. Para poder utilizarla tenemos un archivo .cs con el siguiente código.
/// <summary>
/// Activate the graph
/// </summary>
/// <param name="Id">Renderer ID</param>
/// <returns>True if success</returns>
[DllImport("DsRender.dll",EntryPoint="RunClient")]
public static extern bool Run(int Id);
Con esto dices que la función RunClient de la dll DsRender se llamará en C# con la función llamada Run.
Espero haverte ayudado!!
Saludos.
Muchas gracias Vicent! el problema de eso es que solo funciona con C.. en cuanto te pones con clases y demas... ya no tira.
He encontrado un par de direcciones muy interesantes, las estoy leyendo pero creo que nos diran el como... por cierto haddd, hablan de que hacer el dllimport puede ser "very time consuming"... con el newton habeis tenido algun problema? algun bottleneck o cosas asi?
Os recomiendo a todos leerlo tranquilamente jeje, yo utilizando recursos de la empresa...lo he sacado por papel y me pondre a ello a ratos ...
http://msdn.microsoft.com/library/en-us/dn....asp?frame=truehttp://msdn.microsoft.com/library/en-us/dn....asp?frame=truehttp://www.codeguru.com/Cpp/Cpp/cpp_manage...icle.php/c6867/Que aproveche su digestion! :D
CitarMuchas gracias Vicent! el problema de eso es que solo funciona con C.. en cuanto te pones con clases y demas... ya no tira
en el ejemplo que te he puesto antes, el objeto pClient[IdClient] es un objeto de una clase llamada CRender... así que en principio si que va con C++ y clases...
Suerte!
bueno, si es o no lento, realmente no lo noto, porque las llamadas a Newton que se hacen son muy opequeñas. Luego Newton ya se encarga por detrás de todos los temas...
Hola,
he mirado lo de Qt#, y lo que hacen ellos es generar un wrapper de QtC que es a su vez un port de Qt a C... Así que por ese camino nada, sorry :( Un saludo,
Vicente
TheAzazel, estube viendo un poco la lib para en un corto tiempo poder empezar con el port haber que tal me va...
El problema seria que habria de portar???
Solo CRM32Pro.dll???
O alguna otra cosa mas???
Voy a tratar de hacer el port en C# directamente y si no se puede luego vemos que pasa...
Adios!!
P.D: Estube viendo un poco el ejemplo de Haddd y segun entendi ademas de portar CRM32Pro.dll habria que portar cada funcion de este y establecer si es bool, int, o lo que sea... Hasta ahora ese seria el maximo problema...
Bueno, no pude esperar y me meti a tratar de hacer algo, lastima que llegue tarde para editar (nooo) .
Para que el trabajo sea sencillo ya que no me conosco la libreria de punta a punta seria bastante agradable conocer cada funcion, que parametro recibe y que devuelve... Claro que de esa forma el trabajo ya estaria muy sencillo, seria solo cuestion de ponerse y portar cada funcion como hizo Haddd es su ejemplo...
Ahora la pregunta
Tienes algun texto donde se expliquen las funciones???
Ahi alguna forma de que pueda verlas???
Supuse que si me conseguia algo tipo Visual Studio seria cuestion de referenciar la libreria estando en un projecto C++ y revisarla... Eh aqui el problema, yo no uso Visual Studio, uso SharpDevelop que es free (Di "no" a la pirateria :P )... Aunque ahora voy a ponerme a revisar si puedo hacer que lea la lib... (espero que si (uoh) )
Edito: Ya eh tratado de ver la librewria desde SharpDevelop y cuando la referencio en un projecto C++.Net y trato de abrirla pone algo como esto:
Citar"No se puede cargar el archivo CRM32Pro.dll en la ubicación C:\Archivos de programa\CRM32Pro. revise los permisos y la existencia de ese archivo."
Y si pido que muestre la excepcion pone:
CitarSystem.OutOfMemoryException: Se inicio una excepcion de tipo System.OutOfMemoryException.
Y ahora que lo leo es lo mismo que pone al intentar reerenciar la lib desde C#
Haber si alguien me da una mano, que para alguien que hace unos meses empezo con C# es dificil... :rolleyes:
P.D: Espero no haberlos aburrido con mis quisas sencillas preguntas... Adios!
Creo que eso es porque estas intentado cargar un dll en C++ unmanaged... ya te comente en otro thread que primero hay que hacer un wrapper de las funciones que encontraras en CRM32Pro.h en C++ managed y luego ya...esa dll la puedes usar en cualquier .NET.
saludos y mucho animo!! al fin alguien se anima echando un cable :P (ojo, sin contar a todos los del logo que los debo una jeje)
Entonces tendria que hacerse todo en Managed C++???
Y porque no en C#???
Marca algun error o algo???
La cuestion es que no tengo ni una minima nocion de C++!
Eso seria un problema??
P.D: Me encontre esto por Internet, haber si sirve de algo...
http://blogs.msdn.com/deeptanshuv/archive/.../26/432870.aspx
TheAzazel si quieres hacer un port a c# u otro lenguaje te aconsejo que crees una dll en c que encapsule todas las clases de c++ que tienes, una funcion que haga el new de la clase, otra que llame a una funcion de la clase indicandole un puntero devuelto por la primera funcion que te dije, etc piense que si estuviera hecho en c a las funciones tendrias que pasarles el puntero a la estructura con lo que seria lo mismo, si no me explico bien dimelo y vuelvo a intentarlo, el unico problema que puedes tener es si el programador tuviera que derivar alguna clase, este sistema es un poco absurdo ya que llamas a una funcion para que esta llame a otra, pero es lo unico que se me ocurre si quieres salir del paso y no tener que modificar toda la libreria que tienes ahora
Encapsular la dll en otra escrita en c es bastante costoso y encima, a la hora de usar la lib desde C#(por ejemplo) las funciones serian distintas...donde en C++ seria un CTile *tile=new CTile pasaria a ser otra cosa y eso no me atrae....
La clave de todo la encontre y lo postee en un post anterior en este mismo thread....
http://msdn.microsoft.com/library/default....arp12192002.asphay explica como hacer un wrapper de una DLL codificada en C++ unmanaged con C++ managed y luego ya, esa nueva DLL que haria de wrapper puede ser utilizada directamente desde cualquier lenguaje .NET.
Gezequiel, mira ese ejemplo y veras que entre C++ managed y C# hay muy muy pocas diferencias a nivel de sintaxis(de hecho, es la misma y no se si habra algun cambio) lo unico es a la hora de definir las clases y definir lo que vas a utilizar..pero en ese documento te lo explica muy bien y en base a el, puedes intentar hacer un wrapper de la interfaz mas sencilla...que seria ILogSystem (al menos con el miembro Init) y cuando consigas que el Init funcione pues puedes ir avanzando... y cuenta conmigo que una mano te podre echar :)
dime que te parece ese doc
Mmm... Parece un link bastante interesante...
Voy a ver si luego le pego una leida y te digo que tal esta la cosa, teniendo en cuenta que no tengo el mejor ingles del mundo (algo es algo :rolleyes: ).
Ahora lo reviso y me pongo a ver que sale...
Ok, visitare el foro luego mas tarde a ver como va el tema :)
Bueno, en un intento rapido, revisando la ayuda de la libreria y el link que dejaste hice algo muy basico, que probablemente este mal, pero quisas asi ustedes (los que saben y sobretodo TheAzazel, que conoce la libreria) pueden ver donde estan los problemas, y quisas asi me empieze a orientarme mas y despues de arreglar varios errores pueda largarme solo... En definitiva, quedo algo asi:
Citar
#include "CRM32Pro.h"
using namespace System;
public __gc class ILogSystem
{
public:
Uint8 CRM32Pro_ILogSystem::GetState ( void )
}
Tengan es cuenta que eso esta incompleto y que no se C++ (apenas se C#), pero veamos que sale...
Esperando sus respuestas me eh encontrado con mas informacion (en ingles por supuesto) sobre wrappers y esas cosas (segun entendi puede hacerse directamente en C#, algo que me quitaria varios quebraderos de cabeza)
Lo dejo sobretodo para alguien que quiera un poco mas de info sobre como se hacen estas cosas...
How can you migrate your existing application?Bueno, espero que les sirva de algo...
Adios!
Siguiendo con mis intentos, esta vez en C#, y siguiendo la idea del link que deje anteriormente, seria algo por el estilo:
Citar
using System;
using System.Runtime.InteropServices;
public class CRM32ProWrapper
{
[DllImport("CRM32Pro.dll", EntryPoint = "CRM32Pro_ILogSystem")]
public static extern void ILogSystem(int a, int B);
}
/* El void y los int a y int b los puse porque no sabia que poner,
* pero ahi tendria que ver que dice TheAzazel, respecto de los
* datos de ILogSystem, pero mientras puse esos ;).
* (Veamos que opina Haddd que es el que sabe de estas cosas de C#...) */
El problema es que de ahi en adelante no se como llamar las funciones de ILogSystem que serian segun lo que entendi:
Citar
Public Member Functions
void Init (char *filename, char mode, char level, char *prgname, char
*author=NULL, char *email=NULL, char *web=NULL)
Init LogSystem.
void Msg (char level, char *,...)
Output a log message.
void DumpSurface (SDL_Surface *surface)
Print surface information.
Uint8 GetState (void)
Get log system state.
void ProfileBegin (char *name)
Mark the begin of profile block.
void ProfileEnd (char *name)
Mark the end of profile block.
void ProfileShow (void)
Print to log system the samples results table.
O se podrian llamar directamente ya que lo otro esta Wrappeado??
(Haddd, tu que tienes experiencia, me guias un poco??)
Haber quien me echa un cable! (ole) :rolleyes: ;)
Hola.
Me he tomado un descanso en el tema de los tutoriales de Haddd y he creado en un momentillo un wrapper en managed C++ para CRM32Pro versión 4.62. Bueno, evidentemente no es un wrapper completo. Sólo he implementado la clase ILogSystem y lo he probado en un cliente en C# y funciona perfectamente. El único impedimento que he encontrado ha sido a la hora de implementar los argumentos de número variable. En unmanaged C++ sería:
void Msg(char level, char *msg, ...)
en managed C++ sólo he visto esta forma:
void Msg(char level, String *msg, Object* arg __gc[])
Con lo cual luego en C# se utilizaría de la siguiente forma:
object[] vargs = new object[] { "Arg0", "Arg1" };
log.Msg(ILogSystem_Level.Normal, "\nTesting Variable Arguments: {0} {1}", vargs);
Pero claro, no mola. Lo ideal sería poder utilizar:
log.Msg(ILogSystem_Level.Normal, "\nTesting Variable Arguments: {0} {1}", "Arg0", "Arg1");
Pero por lo que he leído, para tener ese tipo de argumentos múltiples hay que modificar el MSIL y bueno, no me he molestado en mirar más en profundidad cómo se haría. :)
En el archivo descargable va el proyecto (VC++ .NET 2003) que envuelve la dll y también un proyecto en C# (VC# Express 2005 Beta2) que sirve para probar el wrapper. También va la distribución de CRM32Pro 4.62 (Win32) que hay en la web de TheAzazel pero he quitado las dll del directorio "Microsoft DLL" porque si no ocupaba bastante más. :)
Descargar.
Saludos.
Ok, gracias BeRSeRKeR!!
Por lo que veo no es muy dificil de C++ nativo a Managed, aunque despues a C# se vuelve un poco mas complejo...
[Offtopic]
Me eh dado cuenta que SharpDevelop, a pesar de poder crear projectos C++ no los puede compilar...
[/Offtopic]
Haber si ahora si entendo, abria que crear una clase llamada en este caso ILogSystem y en esa poner todas las funciones que en esta se incluyen, en el caso del ejemplo de BeRSeRKeR seria Msg y los parametros o lo que sea que va entre parentesis seria exactamente lo mismo pero en su version de .Net como es el caso de "char" a "string". Lo que no entendí fue porque en C++.Net tambien ahy que agregar "Object* arg __gc[]"
Eso seria en todos los casos??
O solo en este y en donde se requiera??
Porque segun tengo entendido eso de __gc es para avisar al compilador o ah quien sabe que es codigo unmanaged, estoy en lo cierto??
Pero porque todo el resto??
Ok, gracias BeRSeRKeR!!
Por lo que veo no es muy dificil de C++ nativo a Managed, aunque despues a C# se vuelve un poco mas complejo...
[Offtopic]
Me eh dado cuenta que SharpDevelop, a pesar de poder crear projectos C++ no los puede compilar...
[/Offtopic]
Haber si ahora si entendo, abria que crear una clase llamada en este caso ILogSystem y en esa poner todas las funciones que en esta se incluyen, en el caso del ejemplo de BeRSeRKeR seria Msg y los parametros o lo que sea que va entre parentesis seria exactamente lo mismo pero en su version de .Net como es el caso de "char" a "string". Lo que no entendí fue porque en C++.Net tambien ahy que agregar "Object* arg __gc[]"
Eso seria en todos los casos??
O solo en este y en donde se requiera??
Porque segun tengo entendido eso de __gc es para avisar al compilador o ah quien sabe que es codigo unmanaged, estoy en lo cierto??
Pero porque todo el resto??
Edit:
Estoy probando unas cosas en C#
Cuando en C++ nativo se pasa como parametro "void" cual seria la equivalencia de este en C#???
Porque si utilizo "void" me da "parametro no valido"
Seria para algo como esto: public static extern byte GetState (void);
Esta mal usado??
Se usa otra cosa??
(!Edite el mensaje anterior y lo agrego como uno nuevo¡)
Ese void no es necesario ponerlo ni en C++ y mucho menos en C#.
En cuanto al __gc, indica que ese recurso es managed, __nogc indica que es unmanaged.
Saludos.
¿el c++ managed usa otro motor de ejecucion o es el mismo que el c#? es que si son diferentes la multiplataforma se iria al garate
Todo lenguaje que sea administrado genera un lenguaje intermedio común (MSIL). Esa es la razón por la que se puede utilizar una dll desarrollada en Managed C++ dentro C# sin tener que hacer nada más que añadirla como referencia.
Saludos.
Necesito la ayuda de algun programador C# para probar un "intento" de portar la libreria a C# directamente sin pasar por C++.
Estaria buscando este programador para que con el wrapper que yo hice trate de crearse algo con CRM32Pro pero desde C# directamente haber que tal va...
Solo por el echo de realizar una prueba...
Si alguien se ofrece el el mismisimo TheAzazel quiere probar C#, ofresco el port...
P.D: Solo esta "wrappeado" CRM32Pro_ILogSystem y todas sus funciones (Init, Msg, DumpSurface, GetState, ProfileBegin, ProfileEnd y ProfileShow)
Vamos, que si este wrapper precario que me arme funciona tendria el wrapper total en unos 2 dias a mas tardar... Asi que eso...
Desenme suerte! Y haber quien se ofrece para hacer la prueba! (si se necesita portar alguna otra funcion para hacer la prueba despues lo vemos...)
Eh tenido unos problemas, haber quien me ayuda...
El codio que trate de implementar para portar lo mas fundamental de CRM32Pro.dll (ILodSystem segun TheAzazel) seria algo por el estilo:
Citar
using System;
using System.Runtime.InteropServices;
namespace CRM32ProWrapper
{
public class CRM32Pro_ILogSystem
{
[DllImport("CRM32Pro.dll", EntryPoint = "CRM32Pro_ILogSystem.Init")]
public static extern void Init (char * filename, char mode, char level, char * prgname, char * author, char * email, char * web);
[DllImport("CRM32Pro.dll", EntryPoint = "CRM32Pro_ILogSystem.Msg")]
public static extern void Msg (char level, char * format);
[DllImport("CRM32Pro.dll", EntryPoint = "CRM32Pro_ILogSystem.DumpSurface")]
public static extern void DumpSurface (SDL_Surface * surface);
[DllImport("CRM32Pro.dll", EntryPoint = "CRM32Pro_ILogSystem.GetState")]
public static extern byte GetState ();
[DllImport("CRM32Pro.dll", EntryPoint = "CRM32Pro_ILogSystem.ProfileBegin")]
public static extern void ProfileBegin (char * name);
[DllImport("CRM32Pro.dll", EntryPoint = "CRM32Pro_ILogSystem.ProfileEnd")]
public static extern void ProfileEnd (char *name);
[DllImport("CRM32Pro.dll", EntryPoint = "CRM32Pro_ILogSystem.ProfileShow")]
public static extern void ProfileShow ();
}
}
Lo que pasa es que me salen errores como:
a)Referenciando a la libreria, me pone:
fatal error CS0009: No se puede abrir el archivo de metadatos -- No existen metadatos en la memoria o secuencia
b)Sin reerenciar a la libreria me pone:
No se puede encontrar el tipo o el nombre de espacio de nombres 'SDL_Surface' (¿falta una directiva using o una reerencia de ensamblado?)
Haber si alguien me da una mano, que haciendolo en C# se me solucionarian varios problemas, y como dije, en don dias ya tendria todo el wrapper echo (suponiendo que hacer el resto de la lib no traeria errores y seria escribir el resto del codgo como al principio)
Bueno, hay unos problemas con ese wrapper que estás intentando hacer. Primero, estás utilizando tipos de datos unmanaged (char *) cuando tendrías que utilizar el equivalente en managed, que es string.
Luego está el tema de la forma en la que estás especificando los puntos de entrada de los métodos de la clase ILogSystem. De esa forma, C# no va a ser capaz de encontrarlos ya que la dll no los expone así.
Yo creo que no se puede llevar a cabo el wrapper de una DLL en C++ a través de C#. Puedo estar equivocado pero por las cosas que he visto, no hay indicios de que se pueda. Que no digo que sea imposible, pero yo no he visto nada que indique lo contrario. Así que la forma de llevar a acabo dicho wrapper es a través de managed C++ y evidentemente no te vas a librar de ciertas complicaciones pero creo que es la forma más directa.
Por ejemplo, yo he hecho el envoltorio para las clases CRM32Pro_ILogSystem y CRM32Pro_IStuffDPF pero no están del todo implementadas.
La clase CRM32Pro_ILogSystem parece funcionar perfectamente excepto el método DumpSurface que tiene como parámetro de entrada una superficie de SDL. Evidentemente este es un tipo unmanaged y habría que hacerlo managed. Una opción sería utilizar alguna implementación managed de SDL (si es que existe).
Luego, la clase CRM32Pro_IStuffDPF también está casi implementada pero nos encontramos con la estructura DPF_BlockData que tiene arrays de longitud fija y un puntero a un buffer de datos. Eso habría que convertirlo a managed. Sé que hay atributos para poder especificar arrays de longitud fija pero no recuerdo cuáles son ahora mismo. Y bueno, el puntero a un buffer se podría tratar como IntPtr y luego me imagino que habría que tener un método para convertir la estructura a unmanaged y viceversa. El caso es que he probado a crear un DPF (en la aplicación cliente en C# que he creado para ir probando el wrapper) y efectivamente lo crea (se escribe la cabecera), pero hasta que no se pase la estructura a managed, no se podrían insertar bloques de datos y demás operaciones posibles.
Le he echado un vistazo rápido al archivo de cabecera de CRM32Pro y te diré las cosas que me parece a mí que te traerán más problemas a la hora de ser implementados.
- Estructuras con arrays de tamaño fijo y punteros a buffers.
- Punteros a SDL_Surface. Por suerte parece que junto con SDL_Rect es el único tipo de las SDL que utiliza CRM32Pro (al menos que se exponga).
- Punteros a funciones. Por ejemplo la función que se llamará al pulsar un botón del ratón. En managed esto se resuelve con delegates.
- Ciertas variables y funciones externas (que no son posibles en managed de la misma forma que en C o C++) como screen, mouse_xpos, mouse_ypos, etc.
En fin, creo que esos son los puntos más peliagudos a la hora de crear el wrapper. Si superas eso, el resto será pan comido. En cualquier caso si alguien arroja luz sobre esos puntos, la cosa será más sencilla. Yo ahora mismo estoy liado creando contenido para Haddd así que mucho no podré hacer pero si tengo algún hueco y esto sigue adelante tal vez podría echar una mano.
Saludos.
Hola,
yo he encontrado dos ports de SDL a .NET:
Port 1Port 2No los he podido mirar y a lo mejor googleando más rato se encuentran más cosas, pero podría ayudar seguramente. Un saludo!
Vicente
Muchas gracias Berserker por ayudar... la verdad es que he visto y probado el wrapper que has hecho de Ilogsystem y pinta muy muy bien :P y gracias tambien por echar un cable a gezequiel (ole)
Por cierto, cuando dije lo de "la intefaz mas facil de wrappear seria ILogSystem" me referia solo al miembro Init...puesto que el Msg telita con los argumentos variables pero ya he visto que has pasado por encima de ellos jeje
Voy a intentar aportar mi granito...
@Gezequiel: en los links de este mismo thread(algunos los puse yo, otros los pusieron los habituales del foro) ponia claramente lo que Berserker intuye: no se puede hacer un wrapper de una DLL escrita en C++ unmanaged directamente sobre C#. Concreto, lo que no se puede hacer es wrappear clases. Luego si el codigo de CRM32Pro fuera C o C++(sin utilizar clases) se podria importar y wrappear tal y como lo has intentado hacer tu. Luego, yo no perderia mas tiempo con ello(intentando hacerlo en C# directamente), el camino correcto es el dado por Berserker(el link que te puse, hacen lo mismo que ha hecho el).
Ah, y todas las pruebas que necesites que alguien te haga... por supuesto cuenta conmigo, me lo mandas por email y lo pruebo en cuanto lo vea y te cuento (el email esta en la web... que viene a ser megastorm(ARROBA)mi.madritel.es).
@Berserker: sobre los puntos que estimas con posibles problemas, puedo resolver algunos y otros no se como hacerlo:
Citar
1.- Estructuras con arrays de tamaño fijo y punteros a buffers.
2.- Punteros a SDL_Surface. Por suerte parece que junto con SDL_Rect es el único tipo de las SDL que utiliza CRM32Pro (al menos que se exponga).
3.- Punteros a funciones. Por ejemplo la función que se llamará al pulsar un botón del ratón. En managed esto se resuelve con delegates.
4.- Ciertas variables y funciones externas (que no son posibles en managed de la misma forma que en C o C++) como screen, mouse_xpos, mouse_ypos, etc.
El punto 1 no sabria como resolverlo(no se C#) pero quizas alguien, aparte de la informacion que das, pueda ayudar para aclarar del todo esto.
El punto 2... tal y como dices...esas dos son las unicas estructuras que CRM32Pro expone.. internamente utiliza mas pero de cara hacia fuera da igual. (Aqui se podria utilizar algun port de SDL a Net para ver como han convertido esas estructuras a managed).
El punto 3...si tu dices que es con delegates...te creo jejeje, yo no tengo ni idea de C# a ese nivel jejeje
Y finalmente, el 4, aqui no hay que preocuparse puesto que para la version que esta llegando, todas las variables/funciones globales van a desaparecer y pasaran a formar parte de una interfaz.
@Vicente: desde luego que esos dos ports ayudaran.... el primer paso seria realizar un wrapper de CRM32Pro pero tambien hay que wrappear luego todas las funciones de SDL, y para esto(que es mas facil al ser codigo C) se puede uno fijar en estos dos wrappers y como lo han hecho.
Resumiendo:
- Wrapper en C++ managed de CRM32Pro (permitira su uso en cualquier .NET)
- Resolver esos puntos indicados por Berserker
- Utilizar los port a NET de SDL para obtener las estructuras SDL_Surface y SDL_Rect en formato managed.
- Importar las funciones y datos de SDL a managed o utilizar el port existente.
Saludos
¿y hacerlo en C# desde 0 ? No es difícil, el motor lo empecé a hacer sin tener ni idea de C# ;)
Hola,
mirando un poco más por internet (respecto al tema de los arrays de tamaño fijo). Creo que el atributo es este:
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]
Parece ser que tiene algo como SizeConst que es para especificar el tamaño del array. La info está sacada de:
MSDNNo lo he podido leer mucho (toy en el curro). Espero que ayude ;) Un saludo!
Vicente
Edit: Acabo de encontrar esto
Fixed-Size Buffers
C# 2.0 expanded the use of the fixed keyword to enable you to create fixed-sized, single-dimension arrays, which are called fixed-size buffers. A fixed-size buffer is always a member of a struct. The purpose of a fixed-size buffer is to allow the creation of a struct in which the array elements that make up the buffer are contained within the struct. Normally, when you include an array member in a struct, only a reference to the array is actually held within the struct. By using a fixed-size buffer, you cause the entire array to be contained within the struct. This results in a structure that can be used in situations in which the size of a struct is important, such as in mixed-language programming; interfacing to data not created by a C# program; or whenever a non-managed struct containing an array is required. Fixed-size buffers can only be used within an unsafe context.
Sale de
aquí.
Cuanta info junta!!
Parece entonces que va a tener que ser directamente en C++.Net :( .
Lamentablemente eso no es lo mio, pero vamos a ver que sale...
Bueno, como primer paso, me estoy descargando el C# 2005, que parece que con mi framework 1.1 estaba un poco desactualizado... :D
Segundo, ya voy a ponerme a leer lo de "Estructuras con arrays de tamaño fijo y punteros a buffers." y otro poco de delegates.
Tercero, para hacer el wrapper, tendrian que hacerse "llamadas" a los metodos de la libreria desde managed, estoy en lo cierto??
Haddd: Me encantaria poder portar toda la libreria directamente a C# (genial) , pero vamos, que si no puedo con unos pasos en C++ unmanaged a managed, toda la libreria se complicaria bastante (nooo) ... Ademas quien sabe, quisas TheAzazel no quiera que se haga eso, y solo este buscando un wrapper para luego hacerlo el, quien sabe ;) .
Bien, creo que por ahora eso es todo, me gusta esto de abrir mi firefox en Stratos y encontrarme con kilos de informacion...
En todo caso edito o agrego otro post si no me deja... :ph34r:
Recien acabo de recordar que hace un tiempo, cuando me disponia a hacer el port de CRM32Pro yo solo (pobre ingenuo :P ) le mande un mail a un podriamos decir "Guru" de la programacion en C# y C++ de aqui de argentina, asi que abri mi Gmail y me puse a buscar el mail, una vez encontrado descubri que si existe una forma de portar la lib a C#, pero que seria muy extenso.
Les copio el mensaje para que vean:
CitarHola, Gaston, mirá el tema de las dlls desde C# es un tema. Si la dll hecha en C++ sólo posee funciones globales (sin clases) hay que hacer una clase C# que invoque cada uno de sus métodos. El tema es si la DLL posee clases (lo cual es bastante común), en dicho caso se complica un poco y es necesario realizar una clase con bastante código para poder hacer uso de la librería (a tal punto que en una ocasión cuando tuve que hacerlo preferí reescribir la DLL).
Si la lib tiene clases y tenés el código fuente de la DLL tal vez te convenga recompilarla en Managed C++ (igual tendrás que hacer algunos cambios)
Jeje, parece que Haddd no estaba tan confundido respecto a lo de crear la Lib directamente el C# otra vez!! :D . Sin embargo parece que con el codigo fuente podria recompilarse y haci hacerlo mas sencillo... o quisas no... jeje XD
Quisas alguien con el Visual Studio podria recompilarlo y pasarlo a Managed para ver si esa alternativa funciona
Está claro que lo mejor es reescribir la dll directamente en managed (cualquier lenguaje administrado). Pero en el caso de que eso no fuera posible, lo mejor es hacer el wrapper en managed C++. El mismo programador al que escribiste lo dice, es muy complicado desarrollar el wrapper en C# para una dll en C++ (y no sabemos el impacto en el rendimiento que tendría).
En, cuanto a recompilar la dll pero en managed C++, no sólo sería recompilar. Habría que hacer bastantes cambios para convertir todos los tipos de datos a managed y otras cosas como el uso de delegates (que no es que sea complicado). En fin, te encuentras con los mismos puntos "calientes" que he mencionado en el mensaje anterior.
Saludos.
En verdad, el echo de tener que tener el wrapper en C++ me ah quitado un poco de ganas, sobretodo porque al ponerme a tratar de escribir algo de codigo me siento un poco perdido y porque el lenguaje en si no me llama demasiado :( .
Pero ahora no quiero abandonar el proyecto :blink: , sobretodo al haber sido uno de los que mas "empujo" el poryecto del port a C#, o desde ahora a Managed C++ ;)
En definitiva, si el paso a Managed C++ es un paso que debe hacerse para poder usar la lib desde C#, pues habra que hacerlo... :huh:
En un momento de inspiracion, creado practicamente por Haddd, se me ocurrio ver que tan dificil seria re-escribir CRM32Pro en C# y segun pude ver no seria tan dificil (o eso creo ahora), ademas, suponiendo que cuento con la ayuda de la genial y siempre bien dispuesta gente de Stratos-AD, el trabajo se reduciria entre un 30% a un 40%.
Quizas solo sean delirios de un amateur que tiene una vaga esperanza de no tener que tocar C++ (ole) , pero para ver si estoy muy equivocado les pongo mi intento (si van a dejar mi animo por el piso, trante de que sea leve :P :D )
Tengo que admitir que con este intento de portar la libreria directamente a C# (este no, sino el que trate de hacer el wrapper) aclaro mucho mis dudas y pense que tal vez, hacerle caso a Haddd me ayudaria a introducirme en la practica y dejar de lado lo teorico suponiendo que el, como yo, empezo con unos conociemientos muy basicos del tema.
Supuse que una forma seria pasar cada parte de CRM32Pro.h con ayuda de, valgame la redundancia, la ayuda y quedo algo mas o menso asi:
Citar
using System;
namespace CRM32Pro
{
public class ILogSystem
{
public void Init(string * filename, string mode, string level, string * prgname, string * author, string * email, string * web);
public void Msg(string level, string * );
public void DumpSurface (SDL_Surface * surface);
public byte GetState ();
public void ProfileBegin (string * name);
public void ProfileEnd (string * name);
public void ProfileShow ();
}
}
Claro que, rapidamente, puede verse un error que es la parte de los * xxx, que en caso de empezar, esa seria la primer ayuda que necesitaria XD.
(Haber para cuando ponen un emoticon asi: XD, que queda muy mal! :P )
Bueno, como les dije, traten de no matarme con sus criticas, una cosa mas, si el proyecto es "factible"
Piensan que es mucho para mi??
O podria tolerar los posibles errores y el intento no seria en vano??
Aclaro algo, luego de las proximas dos semanas, en las cuales voy a estar "atareadisimo", voy a tener muuuuuuuucho tiempo para dedicarle al posible port y tambien a juegario.com.ar, que se abran dado cuenta lo deje bastante de lado en el ultimo tiempo.
Adios! y espero no haberles echo desperdiciar mucho tiempo... (ole)
Hola,
en C# no existen los punteros ya que las clases son tipos por referencia (usease, un puntero). Vamos, que la solución es simple, te sobra el * :P
Además piensalo: en C eso era un char*, usease un array de caracteres (porque un nombre de fichero es un array de caracteres). Un string es también un array de caracteres, con lo cual para que necesitas el * ese? :P
De todas formas, quizás a lo mejor antes de portar la librería prueba a escribirte pequeños programas en C# para cogerle el truquillo, y ya luego portas la librería. Un saludo!
Vicente
Reescribir la libreria en C# es un curro enorme... y su posterior mantenimiento mas aun... a mi esa idea me hace "tendiendo a 0"...
Vereis, la libreria seguira siendo desarrollada en C++ por el tema multiplataforma y porque es el lenguaje que me permite hacer todo lo que quiero(trabas->0). El tema del wrapper a Net seria para que la gente que quiera usar Net lo pueda hacer.
Por mi parte, no tengo ningun problema en enviar el codigo a quien quiera intentar hacer algo con el pero es que sigo pensando que reescribirlo todo en C# para llevar paralelamente dos desarrollos de la misma lib es mas que una locura.
Gezequiel, yo creo que si puedes hacerlo, esta claro que aun te faltan mas conocimientos pero da igual, la experiencia y el conocimiento lo iras ganando. Lo que necesitas es aclarar las ideas, la unica solucion factible que he visto desde el principio y sigo viendo es intentar hacer el wrapper via C++ managed (lo que ha hecho Berserker es el camino que hay que seguir). Realmente no veo mucha diferencia entre el C++ managed y el C#, son unas cuantas cosillas pero tienen mucho en comun luego quitando el nombre de "C++" que puede asustar..el resto es "facil".
En el post anterior puse mas o menos todos los hot spots que gracias a Berserker han quedado reconocidos... tu piensa si quieres y te gusta intentar hacerlo, por poder, claro que puedes, pero si no te gusta tampoco te sientas forzado eh? :) es muy gratificante que estes poniendo tanto interes en el tema pero si ves que no te llama la atencion no pasa nada eh?
Ahora..anda que no molaria tener el wrapper para usarlo desde C#...la de nuevos adeptos que se cazaria jejeje
Leer el post anterior me ah dado unas inmensas ganas de volver a intentarlo, pero esta vez voy a tratar de empezar tranquilo, sin desesperarme por encontrar algun resultado (primero quiero terminar con mis examanes asi que estaria empezando en unas 2 semanas, si alguien quiere hacerlo antes, yo no tengo problema)
Una cosa fundamental que necesitaria (para empezar bien de abajo) es algo que compile Managed C++ porque SharpDevelop (mi IDE de C#) crea proyectos pero no los compila...
Otra: Si alguien se encuentra algo como lo que puso TheAzazel sobre el wrapper pero que no este en ingles, seria una ayuda muy importante.
Bueno, el resto lo veria despues...
Citar
la de nuevos adeptos que se cazaria jejeje
Yo prometo ser el primero en intentar algo!
[off-topic]
¿que ventajas tiene el c++ managed respecto al c#? es decir, ¿se puede trabajar con punteros y te olvidas de los delete, etc? yo es que lo probe una vez un par de horas y no me convencio, me gusto mas el c++ de toda la vida y el c# actual
[/off-topic]
Cita de: zupervaca[off-topic]
¿que ventajas tiene el c++ managed respecto al c#? es decir, ¿se puede trabajar con punteros y te olvidas de los delete, etc? yo es que lo probe una vez un par de horas y no me convencio, me gusto mas el c++ de toda la vida y el c# actual
[/off-topic]
No tengo ni warra... a ver algun experto que opina jeje
Estooo, creo que no tiene ventajas :P Es simplemente para intentar convencer a los programadores C++ recalcitrantes a que se pasen a .NET si no quieren usar C#.
Es broma ;) Pero creo que no tiene ninguna ventaja respecto a C# la verdad... Un saludo!
Vicente
yo soy fanatico de c++ y me quedo con c# antes que con c++ managed ;), puede que sea un bicho raro o simplemente me guste la comodidadde este ultimo :lol: