Which Smalltalk object should be passed to a C function expecting const char* - smalltalk

I want to call the following C function:
int ssh_userauth_password (ssh_session session, const char * username, const char * password)
But regular Smalltalk strings are not working:
library ssh_login: session userAuth: nil password: 'myPwd'.
session is a pointer that i already have and works ok.
But const char * are not mapped to normal string.
Is there any class to map this ?
Also i tried with CPointer and asByteArray but both fail.

You need to pass a CPointer object. Easiest way to do that is via 'yay' gcCopyCStringToHeap. Alternatively thereā€˜re variations like gcCopyUnicodeStringToHeap.

Related

Pass LPWSTR to C# [duplicate]

I need to convert my SHA1 (wchar_t*) to a normal String^ in order to use it in a certain function. Any ideas? I tried Google but all the results were the exact opposite of my question. :\
NOTE: I am using C++.NET framework and Windows Forms Applications
Use the constructor; like this:
const wchar_t* const pStr1 = ...;
System::String^ const str1 = gcnew System::String(pStr1);
const char* const pStr2 = ...;
System::String^ const str2 = gcnew System::String(pStr2);
If you're using the standard C++ string classes (std::wstring or std::string), you can get a pointer with the c_str() method. Your code then might be
const std::wstring const std_str1 = ...;
System::String^ const str1 = gcnew System::String(std_str1.c_str());
See System.String and extensive discussion here.
If on doing Dan's solution you get an error cannot convert parameter 1 from 'std::string' to 'const wchar_t *', then you're asking the wrong question. Instead of asking how to convert wchar_t* to String^, you should be asking how to convert std::string to String^.
Use the built-in c_str function to get a plain char* out of the std::string, and pass that to the constructor.
std::string unmanaged = ...;
String^ managed = gcnew String(unmanaged.c_str());
You could also try:
#include <msclr\marshal_cppstd.h>
...
String^ managedString = msclr::interop::marshal_as<String^>(/* std::string or wchar_t * or const wchar_t * */);
You can refer to Overview of Marshaling in C++ for all the supported types you could use

StringToCoTaskMemUni or StringToCoTaskMemAnsi methods can cause hang?

I have the below code in c++/CLI and observing hang while converting the .net string to char * using StringToCoTaskMemAnsi
const char* CDICashInStringStore::CDIGetStringVal( void )
{
unsigned int identifier = (unsigned int)_id;
debug(" cashincdistores--routing call to .Net for CDI String %d", identifier);
NCR::APTRA::INDCDataAccess::IStringValue^ stringValueProvider = (NCR::APTRA::INDCDataAccess::IStringValue^)GetStringProvider()->GetProvider();
String^ strValue = stringValueProvider->GetStringValue(identifier);
debug(" cashincdistores-- going to call StringToCoTaskMemAnsi);
IntPtr iPtr = Marshal::StringToCoTaskMemAnsi(strValue);
debug(" cashincdistores-- StringToCoTaskMemAnsi called);
// use a local (retVal is not needed)
const char * ansiStr = strdup((const char *) iPtr.ToPointer());
Marshal::FreeCoTaskMem(iPtr);
debug(" cashincdistores--got results %d %s",identifier,ansiStr);
// The returned memory will be free() 'ed by the user
return ansiStr;
}
In our logging I can see "cashincdistores-- going to call StringToCoTaskMemAnsi" and suspecting there is a hang after calling the 'StringToCoTaskMemAnsi' method.
Does there is a chance of hang in 'StringToCoTaskMemAnsi' marshalling method. what could cause the hang ?
Why are you using COM in the first place? You don't need any COM in that code.
Disclaimer: You should probably not be returning a const char * someone else will have to free from your function. That's a very easy way to produce memory leaks or multiple free errors.
Ignoring the disclaimer above, you have a couple possibilities:
First way:
#include <msclr/marshal.h>
msclr::interop::marshal_context context;
const char* strValueAsCString = context.marshal_as<const char*>(strValue);
// Probably bad
const char* ansiStr = strdup(strValueAsCString);
The strValueAsCString pointer will remain valid as long as context is in scope.
Another way:
#include <string>
#include <msclr/marshal_cppstd.h>
std::string strValueAsStdString = msclr::interop::marshal_as<std::string>(strValue);
// Probably bad
const char* ansiStr = strdup(strValueAsStdString.c_str());
Here, the std::string manages the lifetime of the string.
See Overview of Marshaling for reference.

Convert System::String to std::string in UTF8, which later converted to char* as c_str

I have a System::String^ variable in C++ code. This variable should be converted to std::string which is later converted to const char* via c_str.
// original string
System::String^ path = ...;
// convert to std::string
msclr::interop::marshal_context context;
std::string filename(context.marshal_as<std::string>(path));
// call API function that internally connects to sqlite3 using sqlite3_open as
// sqlite3_open(filename.c_str())
// https://www.sqlite.org/c3ref/open.html -
// const char *filename, /* Database filename (UTF-8) */
doCalculation(filename)
It works well with the ASCII paths, but fails if the path contains non-latin characters.
So Somehow I need to convert marshalled std::string from current implementation (ASCII?) to UTF8.
I've tried
std::wstring dbPath(context.marshal_as<std::wstring>(path));
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;
std::string dbPathU8 = convert.to_bytes(dbPath);
but it does not work.
What you want to do is use the .Net methods to convert directly to UTF-8.
The available methods in the Encoding class aren't exactly what you're looking for (direct from managed String to unmanaged string or byte array), so we'll need an intermediary and some manual copying.
String^ path = ...;
// First, convert to a managed array of the bytes you want.
array<Byte>^ bytes = Encoding::UTF8->GetBytes(path);
// Then, copy those bytes from the managed byte array to an unmanaged string.
std::string str;
str.resize(bytes->Length);
Marshal::Copy(bytes, 0, IntPtr(str.data()), bytes->Length);
// OR, copy directly to the char* you want eventually.
char* chars = new char[bytes->Length + 1]; // or malloc(), or whatever.
Marshal::Copy(bytes, 0, IntPtr(chars), bytes->Length);
chars[bytes->Length] = '\0'; // null terminate.
// don't forget to free the buffer when you're done with it!
There are several GetBytes variants available, but the parameters to them seem to either be both managed, or both unmanaged. (String^ and array^, or char* and byte*, but not String^ and byte*.) Therefore, we have the Encoding class create a managed byte array, then we use the Marshal::Copy method to copy those bytes either to the unmanaged string object, or directly to a char*.

SSH Keyboard Interactive authentication

I currently try to extend an libssh2 Wrapper in Objective-C.
I'm trying to implement the libssh2_userauth_keyboard_interactive method. My problem is the response callback.
I found this implementation on the net that bypasses the "real" interactivity and uses the actual password to make the authentication possible:
int error = libssh2_userauth_keyboard_interactive(session, [username UTF8String], &kbdCallback);
static void kbdCallback (const char *name, int name_len, const char *instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract)
{
responses[0].text = (char *)[password UTF8String]; // resp. (char *)[#"test" UTF8String]
responses[0].length = strlen([password UTF8String]); // resp. (char *)[#"test" UTF8String]
}
One of my problems is to access the instance variable password within the static void call and my other problem is that I get SIGABRT when I try to call the method (I used a fixed string to test if that works).
Is there any possibility to get that working ?!
Julian
kbdCallback is not actually a method, it's a function - you can tell a couple of ways - there's no - or + in front of it, no parentheses around the return type, and also methods cannot be static. So, due to it being a function and not a method, there is no object associated with it, and no self pointer; thus you cannot get to any instance variables directly. There's a couple of ways to solve this I suppose; you could have a static instance of your object that the function could get the password from, or if there's some way to pass a context pointer to be used in the callback you might be able to pass an object in that way.
Regarding your SIGABRT, can you say which line exactly that happens on, and what the values of the arguments that you're using are? It's not clear from your question.
http://comments.gmane.org/gmane.network.ssh.libssh2.devel/4163
Cause: malloc-in-EXE-free-in-DLL under Win32.
Fix: Use custom free/malloc/realloc functions. Add below
static void *my_alloc(size_t count, void **abstract) { return malloc(count);}
static void my_free(void *ptr, void **abstract) { free(ptr);}
static void *my_realloc(void *ptr, size_t count, void **abstract){ return realloc(ptr, count);}
And replace
libssh2_session_init();
with
libssh2_session_init_ex(my_alloc, my_free, my_realloc, NULL);

How do I convert a System::String^ to const char*?

I'm developing an app in C++/CLI and have a csv file writing library in unmanaged code that I want to use from the managed portion. So my function looks something like this:
bool CSVWriter::Write(const char* stringToWrite);
...but I'm really struggling to convert my shiny System::String^ into something compatible. Basically I was hoping to call by doing something like:
if( m_myWriter->Write(String::Format("{0}",someValueIWantToSave)) )
{
// report success
}
using namespace System::Runtime::InteropServices;
const char* str = (const char*) (Marshal::StringToHGlobalAnsi(managedString)).ToPointer();
From Dev Shed.
As mcandre mentions, Marshal::StringToHGlobalAnsi() is correct. But don't forget to free the newly allocated resource with Marshal::FreeHGlobal(), when the string is no longer in use.
Alternatively, you can use the msclr::interop::marshal_as template to create the string resource and automatically release it when the call exits the resource's scope.
There's a list of what types need which conversion in the overview of marshalling in C++.