Conversion of C++/CLI array of strings to native C++ char**

In C++/CLI, What's the most efficient way to convert an array of strings to native char**?

I am doing this:

array<String^>^ tokenArray = gcnew array<String^> {"TokenONE", "TokenTWO"};
int numTokens = tokenArray->Length;
char** ptr = new char* [numTokens];
for(int i = 0; i < numTokens; i++)
    {
        // See: http://stackoverflow.com/questions/6596242/
        array<Byte>^ encodedBytes = Text::Encoding::UTF8->GetBytes(tokenArray[i]);
        pin_ptr<Byte> pinnedBytes = &encodedBytes[0];
        ptr[i] = reinterpret_cast<char*>(pinnedBytes);
    }
int myResult = someNativeFunction(ptr, numTokens);
delete ptr;
// ...

What, if anything should be improved? Is this ok from a memory management point of view? I can change the parameters of someNativeFunction if need be.

 Answer

Apart from the problem with pinned pointers going out of scope before being passed tosomeNativeFunction(), the code can be simplified for better clarity especially if you're using MSVC2008 or newer. See this page for information on how to convert a single string (extending to an array should be trivial).

Edited:

If you need ANSI strings const char* then making a copy is inevitable since .NET Strings are Unicode (UTF-16). On MSVC2008 and newer, your code may look as follows:

#include <msclr/marshal.h>
using namespace msclr::interop;

marshal_context context;
array<String^>^ tokenArray = gcnew array<String^> {"TokenONE", "TokenTWO"};
char** tokensAsAnsi = new char* [tokenArray->Length];

for(int i = 0; i < tokenArray->Length; i++)
{
    tokensAsAnsi[i] = context.marshal_as<const char*>(tokenArray[i]);
}
int myResult = someNativeFunction(ptr, tokensAsAnsi);

// The marshalled results are freed when context goes out of scope
delete[] tokensAsAnsi;    // Please note you must use delete[] here!

This does similar job to your code sample but without the need of pointer pinning andreinterpret_cast-ing.

If you are willing to deal with wide string const wchar_t* in someNativeFunction(), you can use the (pinned) internal data directly, However, you'll have to ensure the pointers remain pinned untilsomeNativeFunction() returns which, as pointed out in the comments, may negatively influence the GC performance.

If you're about to marshall many strings and performance is of utmost concern, you could split the marshalling across several threads before passing everything to someNativeFunction(). Before doing that, I'd reccommend profiling your application to see if the conversion really is a bottleneck or whether it's better to focus efforts elsewhere.

Edited #2:

To get the native string in UTF-8 encoding, you can do with a modified version of your code:

array<String^>^ tokenArray = gcnew array<String^> {"TokenONE", "TokenTWO"};
char** tokensAsUtf8 = new char* [tokenArray->Length];

for(int i = 0; i < tokenArray->Length; i++)
{
    array<Byte>^ encodedBytes = Text::Encoding::UTF8->GetBytes(tokenArray[i]);

    // Probably just using [0] is fine here
    pin_ptr<Byte> pinnedBytes = &encodedBytes[encodedBytes->GetLowerBound(0)];

    tokensAsUtf8[i] = new char[encodedBytes->Length + 1]; 
    memcpy(
        tokensAsUtf8[i], 
        reinterpret_cast<char*>(pinnedBytes),
        encodedBytes->Length
        );

    // NULL-terminate the native string
    tokensAsUtf8[i][encodedBytes->Length] = '\0'; 

}
int myResult = someNativeFunction(ptr, tokensAsAnsi);

for(int i = 0; i < tokenArray->Length; i++) delete[] tokensAsUtf8[i];
delete[] tokensAsUtf8;    

If you're concerned about speed, you could pre-allocate a large buffer for the native strings (if you know there will only be a limited amount) or use pool storage.

转自:http://stackoverflow.com/questions/7190987/conversion-of-c-cli-array-of-strings-to-native-c-char

// 获取坐标系对象的关键代码 NXOpen::NXObject* csysObj = orientGeometry->GetObject("CSYS_OBJECT"); if (!csysObj) { theUI->NXMessageBox()->Show("错误", NXMessageBox::DialogTypeError, "无法获取坐标系对象"); return errorCode; }这里加了无法创建坐标,:“#ifndef NXOpen_CAM_CAMOBJECT_HXX_INCLUDED #define NXOpen_CAM_CAMOBJECT_HXX_INCLUDED //-------------------------------------------------------------------------- // Copyright 2024 Siemens //-------------------------------------------------------------------------- // Header for C++ interface to JA API //-------------------------------------------------------------------------- // // Source File: // CAM_CAMObject.ja // // Generated by: // apiwrap // // WARNING: // This file is automatically generated - do not edit by hand // #ifdef _MSC_VER #pragma once #endif #include <NXOpen/NXDeprecation.hxx> #include <vector> #include <NXOpen/NXString.hxx> #include <NXOpen/Callback.hxx> #include <NXOpen/CAM_Path.hxx> #include <NXOpen/NXObject.hxx> #include <NXOpen/libnxopencpp_cam_exports.hxx> #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4996) #endif #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif namespace NXOpen { namespace CAM { class CAMObject; } namespace CAM { class Path; } class NXObject; namespace CAM { class _CAMObjectBuilder; class CAMObjectImpl; /** Represents interface for all CAM Object <br> To create or edit an instance of this class, use @link NXOpen::CAM::ParamBuilder NXOpen::CAM::ParamBuilder @endlink <br> <br> Created in NX4.0.0. <br> */ class NXOPENCPP_CAMEXPORT CAMObject : public NXOpen::NXObject { /** The unit of feed rate */ public: enum FeedRateUnit { FeedRateUnitNone/** no feed rate unit*/, FeedRateUnitPerMinute/** use per minute as the feed rate unit*/, FeedRateUnitPerRevolution/** use per revolution as the feed rate unit */ }; /** Represents the CAM attribute type. */ public: enum Attr { AttrProjDiffTaxis/** proj diff taxis */ = 1, AttrProfileFlipMside/** profile flip mside */ , AttrBndSplineTangent/** bnd spline tangent */ , AttrBlankNormalDiffTaxis/** blank normal diff taxis */ , AttrBndHasSleepObj/** bnd has sleep obj */ , AttrClrnrNotParallelTaxis/** clrnr not parallel taxis */ , AttrBndNotParallelFloor/** bnd not parallel floor */ , AttrFloorNotUpToDate/** floor not up to date */ , AttrSingleProfileWithFirstCut/** single profile with first cut */ , AttrCutterConversionProblem/** cutter conversion problem */ , AttrPredefinedDepthConversionProblem/** predefined depth conversion problem */ , AttrAcceptDrivePosition/** accept drive position */ = 100, AttrReparametrization/** reparametrization */ = 110, AttrBetweenFromStart/** between from start */ = 120, AttrCurveCutRange/** curve cut range */ = 130, AttrFixGssmCornerData/** fix gssm corner data */ = 140, AttrPlmConversion/** plm conversion */ = 150, AttrPlmFeedcomp/** plm feedcomp */ , AttrPlmFillet/** plm fillet */ , AttrPlmSlowdown/** plm slowdown */ , AttrPlmGeometry/** plm geometry */ , AttrWedmPoints/** wedm points */ = 160, AttrCavityMillInheritTrimBnds/** cavity mill inherit trim bnds */ = 170, AttrRtdObsolete/** rtd obsolete */ = 1000, AttrZlevelHolderParamChange/** zlevel holder param change */ = 2000, AttrNcmObsoleteSeqControl/** ncm obsolete seq control */ = 2100, AttrNcmObsoleteCustomFeed/** ncm obsolete custom feed */ , AttrNcmObsoleteLocalRetract/** ncm obsolete local retract */ , AttrNcmClearTraversalZero/** ncm clear traversal zero */ , AttrNcmObsoleteEngretToClearance/** ncm obsolete engret to clearance */ , AttrGmcInvalidNxVersion/** gmc invalid nx version */ = 2201, AttrProbingInvalidNxVersion/** probing invalid nx version */ , AttrInspPathInvalidNxVersion/** insp path invalid nx version */ = 2300, AttrCustomDataGougingObsolete/** custom data gouging obsolete */ , AttrCustomDataGougingPartObsolete/** custom data gouging part obsolete */ , AttrCustomDataGougingDriveObsolete/** custom data gouging drive obsolete */ , AttrCustomDataIgnoreLoopsObsolete/** custom data ignore loops obsolete */ , AttrCustomDataIgnoreLoopsRemoved/** custom data ignore loops removed */ , AttrLimitToolRunOn/** limit tool run on */ = 2400, AttrScoprNcmChangeLinearNormalToPart/** scopr ncm change linear normal to part */ , AttrPossibleToolAxisProblem/** possible tool axis problem */ }; /** The status of the object */ public: enum Status { StatusComplete/** Object path has been output */, StatusRepost/** Object path must be post-processed */, StatusRegen/** Object path must be regenerated */, StatusApproved/** Object path has been approved as is */ = 4 }; /** Error Item */ public: struct ErrorItem { public: /** objecttag */ NXOpen::CAM::CAMObject * ObjectTag; public: /** errorcode */ int ErrorCode; public: ErrorItem() : ObjectTag(), ErrorCode() { } /** Constructor for the ErrorItem struct. */ public: ErrorItem(NXOpen::CAM::CAMObject * objectTagInitial /** objecttag */ , int errorCodeInitial /** errorcode */ ) : ObjectTag(objectTagInitial), ErrorCode(errorCodeInitial) { } }; /** Validation Types */ public: enum ValidationType { ValidationTypeGouge/** gouge */ = 1, ValidationTypeToolHolderCollision/** tool holder collision */ , ValidationTypeToolRapidCollision/** tool rapid collision */ , ValidationTypeHasPath/** has path */ , ValidationTypeSuspectPath/** suspect path */ , ValidationTypeFeedsSpeeds/** feeds speeds */ }; /** Validation Result */ public: enum ValidationResult { ValidationResultNotApplicable/** not applicable */ , ValidationResultOk/** ok */ , ValidationResultNotChecked/** not checked */ , ValidationResultFail/** fail */ }; private: CAMObjectImpl * m_camobject_impl; private: friend class _CAMObjectBuilder; protected: CAMObject(); public: ~CAMObject(); /** Set an integer value to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SetIntegerValue ( const NXString & title /** the name of the parameter index */, int value /** the integer value */ ); /** Set an integer value to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ void SetIntegerValue ( const char * title /** the name of the parameter index */, int value /** the integer value */ ); /** Set a real value to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SetRealValue ( const NXString & title /** the name of the parameter index */, double value /** the real value */ ); /** Set a real value to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ void SetRealValue ( const char * title /** the name of the parameter index */, double value /** the real value */ ); /** Set a string value to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SetStringValue ( const NXString & title /** the name of the parameter index */, const NXString & value /** the string value */ ); /** Set a string value to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ void SetStringValue ( const char * title /** the name of the parameter index */, const char * value /** the string value */ ); /** Set a boolean value to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SetBooleanValue ( const NXString & title /** the name of the parameter index */, bool value /** the boolean value */ ); /** Set a boolean value to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ void SetBooleanValue ( const char * title /** the name of the parameter index */, bool value /** the boolean value */ ); /** Set a object to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SetObject ( const NXString & title /** the name of the parameter index */, NXOpen::NXObject * value /** the object */ ); /** Set a object to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ void SetObject ( const char * title /** the name of the parameter index */, NXOpen::NXObject * value /** the object */ ); /** Set feed rate value and unit to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SetFeedRate ( const NXString & title /** the name of the parameter index */, double value /** the feed rate value */, NXOpen::CAM::CAMObject::FeedRateUnit unit /** the feed rate unit */ ); /** Set feed rate value and unit to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ void SetFeedRate ( const char * title /** the name of the parameter index */, double value /** the feed rate value */, NXOpen::CAM::CAMObject::FeedRateUnit unit /** the feed rate unit */ ); /** Set feed rate value and side to the parameter index for the object, side is only used in wire edm. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SetWireEdmFeedRate ( const NXString & title /** the name of the parameter index */, double value /** the feed rate value */, int side /** Inside = 0, Outside = 1 */ ); /** Set feed rate value and side to the parameter index for the object, side is only used in wire edm. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ void SetWireEdmFeedRate ( const char * title /** the name of the parameter index */, double value /** the feed rate value */, int side /** Inside = 0, Outside = 1 */ ); /** Set feed rate display color to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SetFeedRateColor ( const NXString & title /** the name of the paramter index */, int value /** the color number*/ ); /** Set feed rate display color to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ void SetFeedRateColor ( const char * title /** the name of the paramter index */, int value /** the color number*/ ); /** Set integer array value to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SetIntegerArrayValue ( const NXString & title /** the name of the parameter index */, const std::vector<int> & value /** the integer array */ ); /** Set integer array value to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ void SetIntegerArrayValue ( const char * title /** the name of the parameter index */, const std::vector<int> & value /** the integer array */ ); /** Set real array to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SetRealArrayValue ( const NXString & title /** the name of the parameter index */, const std::vector<double> & value /** the real array */ ); /** Set real array to the parameter index for the object. <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ void SetRealArrayValue ( const char * title /** the name of the parameter index */, const std::vector<double> & value /** the real array */ ); /** Set string array to the parameter index for the object <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SetStringArrayValue ( const NXString & title /** the name of the parameter index */, std::vector<NXString> & value /** the string array */ ); /** Set string array to the parameter index for the object <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ void SetStringArrayValue ( const char * title /** the name of the parameter index */, std::vector<NXString> & value /** the string array */ ); /** Set object array to the parameter index for the object <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SetObjectArrayValue ( const NXString & title /** the name of the parameter index */, const std::vector<NXOpen::NXObject *> & value /** the object array */ ); /** Set object array to the parameter index for the object <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ void SetObjectArrayValue ( const char * title /** the name of the parameter index */, const std::vector<NXOpen::NXObject *> & value /** the object array */ ); /** Get the integer value of the parameter index from the object. @return the integer value <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: int GetIntegerValue ( const NXString & title /** the name of the parameter index */ ); /** Get the integer value of the parameter index from the object. @return the integer value <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ int GetIntegerValue ( const char * title /** the name of the parameter index */ ); /** Get the real value of the parameter index from the object. @return the real value <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: double GetRealValue ( const NXString & title /** the name of the parameter index */ ); /** Get the real value of the parameter index from the object. @return the real value <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ double GetRealValue ( const char * title /** the name of the parameter index */ ); /** Get the boolean value of the parameter index from the object @return the boolean value <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: bool GetBooleanValue ( const NXString & title /** the name of the parameter index */ ); /** Get the boolean value of the parameter index from the object @return the boolean value <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ bool GetBooleanValue ( const char * title /** the name of the parameter index */ ); /** Get the string value of the parameter index from the object @return the string value <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: NXString GetStringValue ( const NXString & title /** the name of the parameter index */ ); /** Get the string value of the parameter index from the object @return the string value <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ NXString GetStringValue ( const char * title /** the name of the parameter index */ ); /** Get the object value of the parameter index from the object @return the object value <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: NXOpen::NXObject * GetObject ( const NXString & title /** the name of the parameter index */ ); /** Get the object value of the parameter index from the object @return the object value <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ NXOpen::NXObject * GetObject ( const char * title /** the name of the parameter index */ ); /** Get the feed rate value and unit of the parameter index from the object @return the feed rate unit <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: NXOpen::CAM::CAMObject::FeedRateUnit GetFeedRate ( const NXString & title /** the name of the parameter index */, double* value /** the feed rate value */ ); /** Get the feed rate value and unit of the parameter index from the object @return the feed rate unit <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ NXOpen::CAM::CAMObject::FeedRateUnit GetFeedRate ( const char * title /** the name of the parameter index */, double* value /** the feed rate value */ ); /** Get the feed rate value and side of the parameter index from the object, side is only used in wire edm. @return the feed rate side <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: int GetWireEdmFeedRate ( const NXString & title /** the name of the parameter index */, double* value /** the feed rate value */ ); /** Get the feed rate value and side of the parameter index from the object, side is only used in wire edm. @return the feed rate side <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ int GetWireEdmFeedRate ( const char * title /** the name of the parameter index */, double* value /** the feed rate value */ ); /** Get the feed rate color of the parameter index from the object. @return the color number <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: int GetFeedRateColor ( const NXString & title /** the name of the parameter index */ ); /** Get the feed rate color of the parameter index from the object. @return the color number <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ int GetFeedRateColor ( const char * title /** the name of the parameter index */ ); /** Get the integer array value of the parameter index from the object. @return the integer array <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: std::vector<int> GetIntegerArrayValue ( const NXString & title /** the name of the parameter index */ ); /** Get the integer array value of the parameter index from the object. @return the integer array <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ std::vector<int> GetIntegerArrayValue ( const char * title /** the name of the parameter index */ ); /** Get the real array value of the parameter index from the object. @return the real array <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: std::vector<double> GetRealArrayValue ( const NXString & title /** the name of the parameter index */ ); /** Get the real array value of the parameter index from the object. @return the real array <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ std::vector<double> GetRealArrayValue ( const char * title /** the name of the parameter index */ ); /** Get the string array value of the parameter index from the object. @return the string array <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: std::vector<NXString> GetStringArrayValue ( const NXString & title /** the name of the parameter index */ ); /** Get the string array value of the parameter index from the object. @return the string array <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ std::vector<NXString> GetStringArrayValue ( const char * title /** the name of the parameter index */ ); /** Get the object array value of the parameter index from the object. @return the object array <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: std::vector<NXOpen::NXObject *> GetObjectArrayValue ( const NXString & title /** the name of the parameter index */ ); /** Get the object array value of the parameter index from the object. @return the object array <br> Created in NX4.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ std::vector<NXOpen::NXObject *> GetObjectArrayValue ( const char * title /** the name of the parameter index */ ); /** Get the status of the input object. @return the object's status <br> Created in NX6.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: NXOpen::CAM::CAMObject::Status GetStatus ( ); /** Remove a specific 911 attribute from an object. <br> Created in NX5.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void Remove911Attribute ( NXOpen::CAM::CAMObject::Attr attrId /** the attribute Id */ ); /** Remove all 911 attributes from an object. <br> Created in NX5.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void RemoveAll911Attributes ( ); /** Check if a 911 attribute exists in an object. @return true -- 911 attribute exists <br> Created in NX5.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: bool Has911Attribute ( NXOpen::CAM::CAMObject::Attr attrId /** the attribute Id */ ); /** Returns the path. Call @link NXOpen::CAM::CAMObject::SavePath NXOpen::CAM::CAMObject::SavePath@endlink after calling @link NXOpen::CAM::CAMObject::GetPath NXOpen::CAM::CAMObject::GetPath@endlink . <br> Created in NX11.0.2. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: NXOpen::CAM::Path * GetPath ( ); /** This must be called to establish proper part status <br> Created in NX11.0.2. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SavePath ( NXOpen::CAM::Path * theBuilder /** thebuilder */ ); /** Tells if the object has a path <br> Created in NX11.0.2. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: bool AskPathExists ( ); /** Create an empty path for the object <br> Created in NX11.0.2. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: NXOpen::CAM::Path * CreateEmptyPath ( ); /** Change the dialog customization of the object to use the explorer dialog style <br> Created in NX12.0.1. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void ConvertToExplorerDialog ( ); /// \cond NX_NO_DOC /** This is an internal API and can be changed at any time <br> Created in NX1872.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SaveMasterPath ( bool inThePart /** save the master path in the same part if true, else in master part*/ ); /// \endcond /// \cond NX_NO_DOC /** This is an internal API and can be changed at any time <br> Created in NX1872.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: bool LoadMasterPathFromPart ( const NXString & masterPathPartName /** Part file with master path */ ); /** This is an internal API and can be changed at any time <br> Created in NX1872.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ bool LoadMasterPathFromPart ( const char * masterPathPartName /** Part file with master path */ ); /// \endcond /// \cond NX_NO_DOC /** This is an internal API and can be changed at any time <br> Created in NX1872.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: bool LoadMasterPath ( ); /// \endcond /// \cond NX_NO_DOC /** This is an internal API and can be changed at any time <br> Created in NX1872.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: bool HasMasterPath ( ); /// \endcond /// \cond NX_NO_DOC /** This is an internal API and can be changed at any time <br> Created in NX1872.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void DeleteMasterPath ( ); /// \endcond /// \cond NX_NO_DOC /** This is an internal API and can be changed at any time <br> Created in NX1872.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void DeleteToolPath ( ); /// \endcond /// \cond NX_NO_DOC /** This is an internal API and can be changed at any time <br> Created in NX1899.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: NXString GetNameOfType ( ); /// \endcond /// \cond NX_NO_DOC /** This is an internal API and can be changed at any time <br> Created in NX1926.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: NXOpen::CAM::CAMObject::ValidationResult GetValidationResult ( NXOpen::CAM::CAMObject::ValidationType validationType /** validationtype */ ); /// \endcond /// \cond NX_NO_DOC /** This is an internal API and can be changed at any time <br> Created in NX2212.0.0. <br> <br> License requirements : cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void UpdateAndNotify ( bool updateAndNotifyMembers /** updateandnotifymembers */ ); /// \endcond }; } } #ifdef _MSC_VER #pragma warning(pop) #endif #ifdef __GNUC__ #ifndef NX_NO_GCC_DEPRECATION_WARNINGS #pragma GCC diagnostic warning "-Wdeprecated-declarations" #endif #endif #undef EXPORTLIBRARY #endif ”
最新发布
10-23
<think>根据您提供的头文件,`CAMObject`类确实有`GetObject`方法,但是您在使用`orientGeometry->GetObject("CSYS_OBJECT")`时返回了空指针。这可能是由于以下原因之一: 1. 坐标系尚未创建或关联到几何体组。 2. 参数名称不正确,在您的情况下应该使用`"MCS"`或`"WORKPIECE_CSYS"`而不是`"CSYS_OBJECT"`。 3. 需要在创建几何体组后设置坐标系。 ### 正确的方法: 在创建几何体组(MCS组)后,我们需要显式设置坐标系。以下是完整的步骤: ```cpp // 获取第一个选择的点 NXOpen::Point* selectedPoint = dynamic_cast<NXOpen::Point*>(selectedPoints[0]); if (selectedPoint) { // 获取点的坐标 NXOpen::Point3d pointCoord = selectedPoint->Coordinates(); // 按照录制代码的方式创建几何体组 // 查找父级几何体组 NXOpen::CAM::NCGroup* parentGeometryGroup = dynamic_cast<NXOpen::CAM::NCGroup*>(workPart->CAMSetup()->CAMGroupCollection()->FindObject("GEOMETRY")); // 创建新的几何体组(MCS) NXOpen::CAM::NCGroup* mcsGroup; mcsGroup = workPart->CAMSetup()->CAMGroupCollection()->CreateGeometry( parentGeometryGroup, "MICH-MB", "MCS_MILL", NXOpen::CAM::NCGroupCollection::UseDefaultNameTrue, "MCS_MILL"); // 转换为OrientGeometry NXOpen::CAM::OrientGeometry* orientGeometry = dynamic_cast<NXOpen::CAM::OrientGeometry*>(mcsGroup); if (!orientGeometry) { theUI->NXMessageBox()->Show("错误", NXMessageBox::DialogTypeError, "MCS对象类型转换失败"); return errorCode; } // 创建坐标系(根据选择的点创建) // 创建坐标系构造器 NXOpen::Features::Feature *feature; NXOpen::CoordinateSystem *coordinateSystem; NXOpen::Features::CoordinateSystemBuilder *coordSysBuilder; coordSysBuilder = workPart->Features()->CreateCoordinateSystemBuilder(nullptr); coordSysBuilder->SetOrigin(pointCoord); feature = coordSysBuilder->CommitFeature(); coordinateSystem = dynamic_cast<NXOpen::CoordinateSystem*>(feature); coordSysBuilder->Destroy(); if (!coordinateSystem) { theUI->NXMessageBox()->Show("错误", NXMessageBox::DialogTypeError, "坐标系创建失败"); return errorCode; } // 将创建的坐标系设置为几何体组的坐标系 orientGeometry->SetObject("MCS", coordinateSystem); // 现在再获取坐标系对象 NXOpen::NXObject* csysObj = orientGeometry->GetObject("MCS"); if (!csysObj) { theUI->NXMessageBox()->Show("错误", NXMessageBox::DialogTypeError, "无法获取坐标系对象"); return errorCode; } // 转换为CoordinateSystem类型(可选,因为我们已经知道它是坐标系) NXOpen::CoordinateSystem* coordSys = dynamic_cast<NXOpen::CoordinateSystem*>(csysObj); if (!coordSys) { theUI->NXMessageBox()->Show("错误", NXMessageBox::DialogTypeError, "坐标系对象类型转换失败"); return errorCode; } // 获取坐标系的tag_t tag_t mcsTag = coordSys->Tag(); // 创建MillOrientGeomBuilder(如果需要) NXOpen::CAM::MillOrientGeomBuilder* millOrientGeomBuilder = workPart->CAMSetup()->CAMGroupCollection()->CreateMillOrientGeomBuilder(orientGeometry); // 后续处理... } ``` ### 关键点解释: 1. **创建坐标系**: - 使用`CoordinateSystemBuilder`以选中的点作为原点创建坐标系。 - 需要显式创建坐标系并关联到几何体组(MCS组)。 2. **设置坐标系到几何体组**: - 使用`SetObject`方法,参数名为`"MCS"`(这是CAM中设置坐标系的参数名)。 - 注意:参数名`"MCS"`是NX CAM中设置坐标系的常用参数名。 3. **获取坐标系**: - 设置后,使用`GetObject("MCS")`获取坐标系对象。 ### 如果仍然无法获取: 如果上述方法仍然无法获取,可能是参数名不正确。您可以通过以下方式检查参数名: ```cpp // 获取所有参数名(用于调试) std::vector<NXString> paramNames = orientGeometry->GetStringArrayValue("ParameterNames"); // 打印所有参数名 for (const NXString& name : paramNames) { theUI->NXMessageBox()->Show("参数名", NXMessageBox::DialogTypeInformation, name.GetText()); } ``` ### 备选方案:使用MillOrientGeomBuilder 另一种更可靠的方法是使用`MillOrientGeomBuilder`来设置坐标系: ```cpp // 创建MillOrientGeomBuilder NXOpen::CAM::MillOrientGeomBuilder* millOrientGeomBuilder = workPart->CAMSetup()->CAMGroupCollection()->CreateMillOrientGeomBuilder(orientGeometry); // 创建坐标系(同上)... // 设置坐标系到Builder millOrientGeomBuilder->SetCsys(coordinateSystem); // 提交Builder millOrientGeomBuilder->Commit(); // 获取坐标系(可以通过Builder) NXOpen::CoordinateSystem* builderCsys = millOrientGeomBuilder->Csys(); tag_t mcsTag = builderCsys->Tag(); // 销毁Builder millOrientGeomBuilder->Destroy(); ``` ### 总结: 1. 创建几何体组(OrientGeometry)。 2. 创建坐标系(使用选中的点)。 3. 使用`SetObject("MCS", coordinateSystem)`将坐标系关联到几何体组,或者使用`MillOrientGeomBuilder`设置坐标系。 4. 获取坐标系的tag_t。 §§相关问题§§: 1. 如何通过NX Open API修改现有坐标系的属性? 2. 在NX CAM中,MCS坐标系的方向如何定义? 3. 如何使用NX Open API创建旋转后的坐标系? 4. 如何删除通过API创建的坐标系? </think>根据您提供的头文件和遇到的错误,问题在于创建几何体组后,坐标系对象尚未被正确初始化或关联。以下是完善的解决方案,包含创建坐标系、设置坐标系到几何体组,然后获取其tag_t的完整流程: ```cpp // 获取第一个选择的点 NXOpen::Point* selectedPoint = dynamic_cast<NXOpen::Point*>(selectedPoints[0]); if (selectedPoint) { // 获取点的坐标 NXOpen::Point3d pointCoord = selectedPoint->Coordinates(); // 查找父级几何体组 NXOpen::CAM::NCGroup* parentGeometryGroup = dynamic_cast<NXOpen::CAM::NCGroup*>(workPart->CAMSetup()->CAMGroupCollection()->FindObject("GEOMETRY")); // 创建新的几何体组(MCS) NXOpen::CAM::NCGroup* mcsGroup; mcsGroup = workPart->CAMSetup()->CAMGroupCollection()->CreateGeometry( parentGeometryGroup, "MICH-MB", "MCS_MILL", NXOpen::CAM::NCGroupCollection::UseDefaultNameTrue, "MCS_MILL"); // 转换为OrientGeometry NXOpen::CAM::OrientGeometry* orientGeometry = dynamic_cast<NXOpen::CAM::OrientGeometry*>(mcsGroup); if (!orientGeometry) { theUI->NXMessageBox()->Show("错误", NXMessageBox::DialogTypeError, "MCS对象类型转换失败"); return errorCode; } // 关键步骤:创建坐标系 ---------------------------- // 创建坐标系构造器 NXOpen::Features::CoordinateSystemBuilder* coordSysBuilder = workPart->Features()->CreateCoordinateSystemBuilder(nullptr); // 设置坐标系原点 coordSysBuilder->SetOrigin(pointCoord); // 提交创建坐标系 NXOpen::Features::Feature* coordSysFeature = coordSysBuilder->Commit(); NXOpen::CoordinateSystem* coordinateSystem = dynamic_cast<NXOpen::CoordinateSystem*>(coordSysFeature); // 销毁构造器 coordSysBuilder->Destroy(); if (!coordinateSystem) { theUI->NXMessageBox()->Show("错误", NXMessageBox::DialogTypeError, "坐标系创建失败"); return errorCode; } // 关键步骤:关联坐标系到几何体组 ------------------- // 使用正确的参数名"MCS"关联坐标系 orientGeometry->SetObject("MCS", coordinateSystem); // 提交更改 orientGeometry->UpdateAndNotify(true); // 获取坐标系对象 -------------------------------- NXOpen::NXObject* csysObj = orientGeometry->GetObject("MCS"); if (!csysObj) { theUI->NXMessageBox()->Show("错误", NXMessageBox::DialogTypeError, "无法获取坐标系对象"); return errorCode; } // 转换为CoordinateSystem类型 NXOpen::CoordinateSystem* coordSys = dynamic_cast<NXOpen::CoordinateSystem*>(csysObj); if (!coordSys) { theUI->NXMessageBox()->Show("错误", NXMessageBox::DialogTypeError, "坐标系对象类型转换失败"); return errorCode; } // 获取坐标系的tag_t tag_t mcsTag = coordSys->Tag(); // 创建MillOrientGeomBuilder NXOpen::CAM::MillOrientGeomBuilder* millOrientGeomBuilder = workPart->CAMSetup()->CAMGroupCollection()->CreateMillOrientGeomBuilder(orientGeometry); // 后续处理... } ``` ### 关键问题解析: 1. **`GetObject("CSYS_OBJECT")`失败原因**: - 创建几何体组时,坐标系尚未创建和关联 - 参数名应为`"MCS"`而非`"CSYS_OBJECT"`(根据CAM API标准) 2. **正确的坐标系创建流程**: ```mermaid graph TD A[创建坐标点] --> B[创建几何体组] B --> C[创建坐标系] C --> D[关联坐标系到几何体组] D --> E[获取坐标系Tag] ``` 3. **核心修复步骤**: - **创建坐标系**:使用`CoordinateSystemBuilder`创建坐标系 - **关联坐标系**:通过`SetObject("MCS", coordinateSystem)`建立关联 - **更新组件**:调用`UpdateAndNotify(true)`提交更改 - **获取对象**:使用`GetObject("MCS")`获取关联的坐标系 4. **参数名对照表**: | 功能 | 正确参数名 | 常见错误名称 | |------|-----------|------------| | 主坐标系 | "MCS" | "CSYS", "CSYS_OBJECT" | | 参考坐标系 | "RCS" | "REF_CSYS" | | 安全平面 | "CLEARANCE_PLANE" | "SAFETY_PLANE" | ### 备选方案:使用MillOrientGeomBuilder 如果上述方法仍然无效,可以直接通过Builder设置坐标系: ```cpp // 创建MillOrientGeomBuilder NXOpen::CAM::MillOrientGeomBuilder* millOrientGeomBuilder = workPart->CAMSetup()->CAMGroupCollection()->CreateMillOrientGeomBuilder(orientGeometry); // 设置坐标系(假设coordinateSystem已创建) millOrientGeomBuilder->SetCsys(coordinateSystem); // 提交Builder更改 millOrientGeomBuilder->Commit(); // 获取坐标系Tag tag_t mcsTag = coordinateSystem->Tag(); // 销毁Builder(重要!) millOrientGeomBuilder->Destroy(); ``` ### 调试建议: 添加以下调试代码检查所有可用参数名: ```cpp // 获取所有参数名 std::vector<NXString> paramNames = orientGeometry->GetStringArrayValue("ParameterNames"); std::string allNames; for (const auto& name : paramNames) { allNames += std::string(name.GetText()) + "\n"; } theUI->NXMessageBox()->Show("参数列表", NXMessageBox::DialogTypeInformation, allNames.c_str()); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值