Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. C# / C++ Interop, Odd behaviour from marshalled strings

C# / C++ Interop, Odd behaviour from marshalled strings

Scheduled Pinned Locked Moved C / C++ / MFC
c++csharpdatabasecom
8 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Mikey_H
    wrote on last edited by
    #1

    Hello, I am trying some Interop in my application. This is the first time I have had to pass arguments with function calls. I am experiencing some odd results.

    // C# Function Call
    RenderEngine.LoadNewMesh("BasicMesh", "Pyramid3", 1);

    // Managed C++ Wrapper Function
    void RenderEngine::LoadNewMesh(String^ meshType, String^ meshName, int nSubsets)
    {
    char* cMeshType = (char*)(void*)Marshal::StringToHGlobalAnsi(meshType);
    char* cMeshName = (char*)(void*)Marshal::StringToHGlobalAnsi(meshName);

    m\_engineRoot->LoadMesh.LoadNewMesh(cMeshType, cMeshName, nSubsets);
    

    }

    // Native C++ Function
    void MeshLoader::LoadNewMesh(char* meshType, char* meshName, UINT nSubsets)
    {
    //char*
    m_meshType = meshType;
    //char*
    m_meshName = meshName;
    m_nSubsets = 0;
    m_nTotalSubsets = nSubsets;

    m\_pMesh							= new BasicMesh();
    
        // This message box will display Pyramid3
        MessageBox(0, meshName, 0, 0);
    
        // This code will not trigger the message box
        if (meshName == "Pyramid3")
                MessageBox(0, (char\*)"meshName is Pyramid3", 0, 0);
    
        // This code will trigger and m\_meshName is set directly as Pyramid3
        // if it is not set directly here the call to GetMeshByName later on returns NULL
    if (strcmp(meshName,"Pyramid3") == 0)
    	m\_meshName = "Pyramid3";
    

    }

    // Object is referenced by name here
    MeshManager::CreateMesh(m_pMesh, m_meshName);

    // Will return NULL if char* is not set directly
    MeshManager::GetMeshByName("Pyramid3");

    C 1 Reply Last reply
    0
    • M Mikey_H

      Hello, I am trying some Interop in my application. This is the first time I have had to pass arguments with function calls. I am experiencing some odd results.

      // C# Function Call
      RenderEngine.LoadNewMesh("BasicMesh", "Pyramid3", 1);

      // Managed C++ Wrapper Function
      void RenderEngine::LoadNewMesh(String^ meshType, String^ meshName, int nSubsets)
      {
      char* cMeshType = (char*)(void*)Marshal::StringToHGlobalAnsi(meshType);
      char* cMeshName = (char*)(void*)Marshal::StringToHGlobalAnsi(meshName);

      m\_engineRoot->LoadMesh.LoadNewMesh(cMeshType, cMeshName, nSubsets);
      

      }

      // Native C++ Function
      void MeshLoader::LoadNewMesh(char* meshType, char* meshName, UINT nSubsets)
      {
      //char*
      m_meshType = meshType;
      //char*
      m_meshName = meshName;
      m_nSubsets = 0;
      m_nTotalSubsets = nSubsets;

      m\_pMesh							= new BasicMesh();
      
          // This message box will display Pyramid3
          MessageBox(0, meshName, 0, 0);
      
          // This code will not trigger the message box
          if (meshName == "Pyramid3")
                  MessageBox(0, (char\*)"meshName is Pyramid3", 0, 0);
      
          // This code will trigger and m\_meshName is set directly as Pyramid3
          // if it is not set directly here the call to GetMeshByName later on returns NULL
      if (strcmp(meshName,"Pyramid3") == 0)
      	m\_meshName = "Pyramid3";
      

      }

      // Object is referenced by name here
      MeshManager::CreateMesh(m_pMesh, m_meshName);

      // Will return NULL if char* is not set directly
      MeshManager::GetMeshByName("Pyramid3");

      C Offline
      C Offline
      Chris Losinger
      wrote on last edited by
      #2

      Mikey_H wrote:

      if (meshName == "Pyramid3")

      the value of meshName is the address of the first character of the string. it is not a string itself. in other words, meshName is a pointer, not a string.

      image processing toolkits | batch image processing

      M 1 Reply Last reply
      0
      • C Chris Losinger

        Mikey_H wrote:

        if (meshName == "Pyramid3")

        the value of meshName is the address of the first character of the string. it is not a string itself. in other words, meshName is a pointer, not a string.

        image processing toolkits | batch image processing

        M Offline
        M Offline
        Mikey_H
        wrote on last edited by
        #3

        The third condition here will result true, as does the second

        if (meshName == "Pyramid3")
        MessageBox(0, (char*)"meshName is Pyramid3", 0, 0);

        if (strcmp(meshName,"Pyramid3") == 0)
        m_meshName = "Pyramid3";

        if (m_meshName == "Pyramid3")
        MessageBox(0, (char*)"m_meshName is Pyramid3", 0, 0);

        modified on Tuesday, April 14, 2009 12:35 PM

        C I 2 Replies Last reply
        0
        • M Mikey_H

          The third condition here will result true, as does the second

          if (meshName == "Pyramid3")
          MessageBox(0, (char*)"meshName is Pyramid3", 0, 0);

          if (strcmp(meshName,"Pyramid3") == 0)
          m_meshName = "Pyramid3";

          if (m_meshName == "Pyramid3")
          MessageBox(0, (char*)"m_meshName is Pyramid3", 0, 0);

          modified on Tuesday, April 14, 2009 12:35 PM

          C Offline
          C Offline
          Chris Losinger
          wrote on last edited by
          #4

          right, because you've assigned meshName to m_meshName, and i assume m_meshName is a string object of some kind, one with an overloaded "==" operator which knows how to compare a C-style (char*) string to its contents. (CString or std::string?) the problem with the first remains: you cannot compare a pointer to a static string. that's not how C-style strings work. and that's why strcmp exists.

          image processing toolkits | batch image processing

          modified on Tuesday, April 14, 2009 11:39 AM

          I 1 Reply Last reply
          0
          • M Mikey_H

            The third condition here will result true, as does the second

            if (meshName == "Pyramid3")
            MessageBox(0, (char*)"meshName is Pyramid3", 0, 0);

            if (strcmp(meshName,"Pyramid3") == 0)
            m_meshName = "Pyramid3";

            if (m_meshName == "Pyramid3")
            MessageBox(0, (char*)"m_meshName is Pyramid3", 0, 0);

            modified on Tuesday, April 14, 2009 12:35 PM

            I Offline
            I Offline
            Iain Clarke Warrior Programmer
            wrote on last edited by
            #5

            The second comparison is the correct one. Two facts you need to know. 1/ m_meshName is a pointer to character. Underneath, it's an integer holding an address in RAM. 2/ The compiler has seen two constant strings in your code, but only bothers to store one copy of the string "Pyramid3" in it's data segment. So, the strcmp works as intended, and makes m_meshName point to the constant string in your code. The 3rd comparison works by luck, as m_meshName is still pointing to that string. This is because your compiler is being efficient, it is not because your code is correct. You are lucky. If this doesn't sink in (it's hard until you have a lightbulb moment), I can recommend reading The Complete Guide to C++ Strings, Part I - Win32 Character Encodings[^] Iain.

            In the process of moving to Sweden for love (awwww). If you're in Scandinavia and want an MVP on the payroll (or happy with a remote worker), give me a job! http://cv.imcsoft.co.uk/[^]

            M 1 Reply Last reply
            0
            • C Chris Losinger

              right, because you've assigned meshName to m_meshName, and i assume m_meshName is a string object of some kind, one with an overloaded "==" operator which knows how to compare a C-style (char*) string to its contents. (CString or std::string?) the problem with the first remains: you cannot compare a pointer to a static string. that's not how C-style strings work. and that's why strcmp exists.

              image processing toolkits | batch image processing

              modified on Tuesday, April 14, 2009 11:39 AM

              I Offline
              I Offline
              Iain Clarke Warrior Programmer
              wrote on last edited by
              #6

              There's no overloading if his comments are right - they're char *'s. So, it's simpler than you thought... See http://www.codeproject.com/script/Forums/View.aspx?fid=1647&msg=3003509[^] for more. Iain.

              In the process of moving to Sweden for love (awwww). If you're in Scandinavia and want an MVP on the payroll (or happy with a remote worker), give me a job! http://cv.imcsoft.co.uk/[^]

              C 1 Reply Last reply
              0
              • I Iain Clarke Warrior Programmer

                There's no overloading if his comments are right - they're char *'s. So, it's simpler than you thought... See http://www.codeproject.com/script/Forums/View.aspx?fid=1647&msg=3003509[^] for more. Iain.

                In the process of moving to Sweden for love (awwww). If you're in Scandinavia and want an MVP on the payroll (or happy with a remote worker), give me a job! http://cv.imcsoft.co.uk/[^]

                C Offline
                C Offline
                Chris Losinger
                wrote on last edited by
                #7

                ah. you're right. i missed that comment.

                image processing toolkits | batch image processing

                1 Reply Last reply
                0
                • I Iain Clarke Warrior Programmer

                  The second comparison is the correct one. Two facts you need to know. 1/ m_meshName is a pointer to character. Underneath, it's an integer holding an address in RAM. 2/ The compiler has seen two constant strings in your code, but only bothers to store one copy of the string "Pyramid3" in it's data segment. So, the strcmp works as intended, and makes m_meshName point to the constant string in your code. The 3rd comparison works by luck, as m_meshName is still pointing to that string. This is because your compiler is being efficient, it is not because your code is correct. You are lucky. If this doesn't sink in (it's hard until you have a lightbulb moment), I can recommend reading The Complete Guide to C++ Strings, Part I - Win32 Character Encodings[^] Iain.

                  In the process of moving to Sweden for love (awwww). If you're in Scandinavia and want an MVP on the payroll (or happy with a remote worker), give me a job! http://cv.imcsoft.co.uk/[^]

                  M Offline
                  M Offline
                  Mikey_H
                  wrote on last edited by
                  #8

                  Iain Clarke wrote:

                  If this doesn't sink in (it's hard until you have a lightbulb moment)

                  My lightbulb is on a dimmer switch... I think I understand what you are saying in your reply. I have just read Part 1, will follow up with Part 2 tomorrow, as it is 4.26am. If my understanding is correct I will be making a lot of changes to my application once I figure this out. Thank you both for your replies. :thumbsup:

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups