-1

I've created a CLR project and now I need to convert a C# textBox.Text property into a C-ansi characters array (null-terminated). I need to pass the text to a C function, something like this:

UPDATE2:

// Form1.h (C#)
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {

myCFunction(textBoxName.Text); // wrong

}

// utils.h (C) - inside the same project as Form1.h
void myCFunction(char* szName);

// utils.cpp (C) - inside the same project as Form1.h
void myCFunction(char* szName)
{
  // do something
}
Bole Grat
  • 71
  • 10
  • 1
    http://stackoverflow.com/questions/2793548/c-sharp-null-terminated-string – xaxxon Jun 09 '13 at 07:44
  • @xaxxon: I believe that's a different situation, as that's converting it for external use - this is for a native function call. – Jon Skeet Jun 09 '13 at 07:49
  • The data is the same regardless. – xaxxon Jun 09 '13 at 07:54
  • @xaxxon: But the method of achieving it is completely different. See my answer, which I believe to be the most appropriate way of doing what the OP wants - using a `BinaryWriter` wouldn't be particularly helpful here, as the OP isn't writing to a stream. – Jon Skeet Jun 09 '13 at 07:59
  • @JonSkeet technically your answer doesn't answer his question. The link I posted does. – xaxxon Jun 09 '13 at 08:03
  • xaxxon, that example is too much work for a simple stuff like this. Do you have any other simpler idea? – Bole Grat Jun 09 '13 at 08:07
  • @xaxxon: I think entirely the opposite, to be honest, but I'm not sure we're going to get anything out of arguing about that. – Jon Skeet Jun 09 '13 at 08:07
  • @BoleGrat comments like that will get you downvotes. – xaxxon Jun 09 '13 at 08:08
  • @xaxxon: They really shouldn't. The comment doesn't affect the quality of the question at all. If you think a comment is inappropriate, flag it. Downvoting the question on that basis is a bad idea IMO. – Jon Skeet Jun 09 '13 at 08:09
  • @JonSkeet I consider voting on questions to be partially about how much the asker is deserving of help. There are two parts to SO questions, right? One is helping the person right now, the other is creating a backlog of answers to questions. The asker is lazy and the question is almost guaranteed to be a dupe, regardless of which question is actually being asked. – xaxxon Jun 09 '13 at 08:11
  • 1
    http://stackoverflow.com/questions/12618747/call-c-function-in-c-sharp-from-dll-strange-parameters – xaxxon Jun 09 '13 at 08:12
  • @xaxxon: No, voting is meant to be on the *content*, not the *person*. I don't see the asker as being lazy here anyway, and if the question is a duplicate I'm pretty sure it's not a duplicate of the one you linked to first. It *may* be a duplicate of the second one, but that's not really clear at the moment. – Jon Skeet Jun 09 '13 at 08:12
  • 1
    "Form1.h" won't be C# code. It may be C++/CLI, but it's not C# code. It's really not clear what you're doing at the moment, I'm afraid. – Jon Skeet Jun 09 '13 at 08:48

2 Answers2

1

If you're passing it into a C function using P/Invoke, I believe the marshaller will just do it for you, based on attributes applied to the parameter in the declaration.

So based on this documentation, you probably want something like:

[DllImport("YourLibrary.Dll")]
public extern void Foo([UnmanagedType.LPStr] string text)
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Jon, I'm not using an external DLL. Will I need to do it? – Bole Grat Jun 09 '13 at 07:55
  • 1
    @BoleGrat: Well where is the C function that you're trying to call. You'll need *some* sort of `extern` call, even if it's a mixed mode assembly. – Jon Skeet Jun 09 '13 at 07:58
  • @BoleGrat: But you're calling the function *from C#*, right? Which means you should have an `extern` declaration in the C# code. That's the declaration that I'm talking about in the answer. Have you actually managed to call a C function *at all* from C# yet? (If this is your first time calling a C function from C#, you've probably got more reading to do first.) – Jon Skeet Jun 09 '13 at 08:08
  • @BoleGrat: Right. So I suggest you start with something you can be more confident in - start with just a function with no parameters at all, and work out how to call that. Then maybe move on to a function with a 32-bit integer parameter - that should be easy to get right - and then move on to strings, using this argument to help you. For example, it's still not even clear where this C function exists. (Is it really in the same DLL as your C# code? I would personally try to avoid that if possible.) – Jon Skeet Jun 09 '13 at 08:11
0
char* str2 = (char*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(textBox1->Text);

Simple.

Bole Grat
  • 71
  • 10
  • You should probably mention, that the memory allocated by `StringToHGlobalAnsi` needs to be manually freed with `FreeHGlobal`. Also important to know is that you can't specify the used encoding. With `StringToCoTaskMemUTF8` (free with `FreeCoTaskMem`) you know that you get proper utf8. – T S Mar 08 '22 at 00:58