Is it possible to implement swscanf_s via swscanf? - c++

I am building a project on android, this project uses many swscanf_s, but android doesn't support swscanf_s, so I wonder is it possible to implement swscanf_s via swscanf?
note: the difference between swscanf_s and swscanf http://en.cppreference.com/w/c/io/fwscanf
swscanf_s: %c, %s, and %[ conversion specifiers each expect two arguments
I have thought about it for a long time
use regular expression to parse the format string, the problem is that android doesn't support vswscanf either.
implement swscanf_s as a variadic template. we can assume all buffer size arguments are integral and other arguments are pointer, so if I can extract all pointer arguments then pass them to swscanf, it will work. unfortunately, I also failed.
Do you have any idea? I hope the implementation wouldn't be too complicated or it will be lower-cost to replace all swscanf_s.
Other solution will also be helpful. Thanks

Related

Transfering v8 types to c++ types (string)

I am making a c++ addon for node.js and I am struggling with passing and getting data. I understood how to transform v8::Number to double, double to v8::Number and int to v8:Number, but I need some more. Mainly, v8::String to std::string and back, v8::Number to int and v8::Array to Array and back. Also it would be great to transfer js objects to some c++ variables, but it is less necessary. Does someone know, how to do that?
P.S. I looked over docs and I found nothing about arrays and objects and only this string a (*v8::String::Utf8Value(args[0]->ToString())) according to strings. But it does not work, I get an error error C2660: v8::Value::ToString: function does not get 0 arguments and error C2512: v8::String::Utf8Value: no suitable default constructor. I do not have any more ideas how to implement that. Can someone help?
And also I tried to do something with returning data from c++. In this way args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, "world").ToLocalChecked()); it works, but if I make like this:
string s = "world";
args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, s).ToLocalChecked());
I get an error error C2664: "v8::MaybeLocal<v8::String> v8::String::NewFromUtf8(v8::Isolate *,const char *,v8::NewStringType,int)": cannot convert argument 2 from "std::string" to "const char *"
And I have no idea what is wrong here. Did someone has exprience working with c++ addons and v8 types, How to do that?
For understanding v8::String, the latest version of the docs help: https://v8docs.nodesource.com/node-14.1/d4/d1b/classv8_1_1_string_1_1_utf8_value.html (some signatures have changed a bit since the days of Node 0.8 -- learning how to make sense of the compiler's error messages is highly recommended if you want to develop with C++!).
For understanding std::string, see some C++ documentation, e.g.: https://en.cppreference.com/w/cpp/string/basic_string
If you need an actual example, you can look at V8's samples/process.cc, which has a function ObjectToString that converts any JS object (e.g. a v8::String) to a std::string. It's only two lines!

resolving network node using boost::asio and an std::wstring

I am using Boost::Asio for network communication. The following code fails with the following compilation error.
Code:
std::wstring hostName(L"myserver");
std::wstring portName(L"myport");
auto query = boost::asio::ip::udp::resolver::query(boost::asio::ip::udp::v4(), hostName, portName);
Compilation error:
Error 1 error C2665: 'boost::asio::ip::basic_resolver_query<InternetProtocol>::basic_resolver_query' :
none of the 5 overloads could convert all the argument types
My questions:
Does Boost::Asio expect ANSI-strings (std::string) only?
Does this mean that hostnames with non-ANSI characters are not supported?
Or do I have to convert my wide strings to UTF8 first?
And in the latter case, does Boost::Asio provide standard methods to do this or can I use my own ANSI/Unicode conversion routines?
Currently running on Windows, using Visual Studio 2013.
Thanks in advance.
Does Boost::Asio expect ANSI-strings (std::string) only? It expects std::string, but not necessarily ANSI, since std::string can store UTF-8.
Does this mean that hostnames with non-ANSI characters are not supported? I haven't personally tried it, but since this is essentially a wrapper on top of the underlying OS networking code, I can't find any reason it wouldn't support using UTF-8.
Or do I have to convert my wide strings to UTF8 first? Most likely, yes, since the wide string format is only used by core Windows APIs, while UTF-8 is used by everyone else including Boost.
And in the latter case, does Boost::Asio provide standard methods to do this or can I use my own ANSI/Unicode conversion routines? Boost doesn't appear to support wide-char. As long as you are using Windows-specific character encoding, you can either use the COM interfaces that are provided by Windows for converting (MultiByteToWideChar, WideCharToMultiByte), or use your own routines. If your own routines are known to be reliable/correct, and you are not already using COM, you might want to stick with your own rather than adding a dependency on COM to your project.

Embedding Python: How to help the scripter?

I'm using Boost to embed Python in my application. For example, I want to check that the following function receives an integer and a string as the first and second parameters (the function is defined in C++).
someFunction(123, 'words')
If I find that the parameters are incorrect, how can I notify the scripter about which line they need to correct, for example?
If you wrap the function using usual def("someFunction",someFunction,...), caller will get automatically notified about c++ signature which could not be matched with objects passed from python, like this (the method takes one dictionary argument, is called with 3 numbers instead):
>>> scene.updateAttrs(1,2,3)
ArgumentError: Python argument types in
Serializable.updateAttrs(Scene, int, int, int)
did not match C++ signature:
updateAttrs(Serializable {lvalue}, boost::python::dict)
Can you post some code to see what is your problem?
Raise an exception with all the information you want them to know, just like you would in Python. In fact, that answer seems so obvious, it makes me think I'm missing something in your question.

sprint_f macro in Linux for cross-platform application

I'm porting an existing Windows application to Linux.
The most of the OS APIs\ Microsoft non-standard extension functions can be easily (more or less...) replaced by equivalent Linux\ GCC APIs, however, I don't know how to deal with sprintf_s which gets variable numbers of arguments.
Does anyone have an idea (If you can please put the code example as well) for that?
Thank you all in advance.
First, can you just port your code to use C++ iostreams instead (for example ostringstream)? This would completely remove all the possible issues with the sprintf line of functions, and if there are a limited number of call points is probably the best option.
If that isn't an option: The sprintf_s function is basically a helper to prevent mistakes (and external abuse to cause buffer overflows. From http://msdn.microsoft.com/en-us/library/ce3zzk1k%28VS.80%29.aspx we learn that it does two things: It checks the format string for valid formats (this doesn't mean it does type checking - it still can't do that), and it allows a max length to be specified.
The best replacement will be snprintf which does have limitations compared to sprintf_s. It won't do format string validation. And not all versions guarantee that the final string will be null terminated: You always want to also store a null into the last character of your buffer after the call to ensure that the final string is null terminated.
Add to end of your header file or beginning of source file:
#ifndef _WIN32
#define sprintf_s(dest,len,format,...) sprintf(dest,format,__VA_ARGS__)
#endif
snprintf has the same signature, but AFAIK it behaves in a slightly different way.
sprintf_s is just a "secure" version (takes buffer length as extra argument) of sprintf , cant you just use sprintf for your port ?
Why not just provide a conditionally compiled implementation of sprintf_s for Linux? This implementation could simply ignore the extra argument and call through to sprintf().

Can I programatically deduce the calling convention used by a C++ dll?

Imagine you'd like to write a program that tests functions in a c++ dll file.
You should enable the user to select a dll (we assume we are talking about c++ dlls).
He should be able to obtain a list of all functions exported by the dll.
Then, the user should be able to select a function name from the list, manually input a list of arguments ( the arguments are all basic types, like int, double, bool or char arrays (e.g. c-type strings) ) and attempt to run the selected function with the specified arguments.
He'd like to know if the function runs with the specified arguments, or do they cause it to crash ( because they don't match the signature for example ).
The main problem is that C++, being a strongly typed language, requires you to know the number and type of the arguments for a function call at compile time.And in my case, I simply don't know what these arguments are, until the user selects them at runtime.
The only solution I came up with, was to use assembly to manually push the arguments on the call stack.
However, I've come to understand that if I want to mess with assembly, I'd better make damn sure that I know which calling convention are the functions in the dll using.
So (finally:) here's my question: can I deduce the calling convention programmaticaly? Dependency Walker won't help me, and I've no idea how to manually read PE format.
The answer is maybe.
If the functions names are C++ decorated, then you can determine the argument count and types from the name decoration, this is your best case scenario, and fairly likely if MSVC was used to write the code in the first place.
If the exported functions are stdcall calling convention (the default for windows api), you can determine the number of bytes to be pushed, but not the types of the arguments.
The bad news is that for C calling convention, there isn't any way to tell by looking at the symbol names. You would need to have access to the source code or the debug info.
http://en.wikipedia.org/wiki/X86_calling_conventions
The name that a function is given as an export is not required to have any relationship with the name that the linker sees, but most of the time, the exported name and the symbol name that the linker sees are the same.
You didn't specify whether you're talking 32-bit or 64-bit here, and the difficulties outlined by you and the other posters mainly apply to 32-bit code. On 64-bit Windows, there's essentially only one calling convention (it's in also in the wikipedia article linked by John Knoeller), which means that you do know the calling convention (of course with the exception of anybody cooking up their own).
Also, with the Microsoft x64 calling convention, not knowing the number of parameters of the function to be called does not stop you from calling it, providing as many parameters as you wish/the user wishes to. This is because you as a caller set aside stack space and clean it up afterwards. -- Of course, not providing the right [number of] parameters may still have the called function do silly things because you're providing invalid input, but that's another story.
The compiled code does not just say 'Here this function is a fastcall, and this one here is stdcall' unfortunately.
Not even modern disassemblers like IDA try to deduce call types by default (there might be a plugin or an option somewhere idk).
Basically if you are a human you cn look at the first few instructions and tell 90% of the time. If they are pop and push, its stdcall, if its passing params through the registers (especially ecx) then its cdecl. Fastcall also uses the registers but does something special.. dunno off the top of my head. But all this info is useless because your program obviously will not be a human.
If you are doing testing, dont you at least have the header files?? This is an awfully hard way to skin a cat..
If you want to know what calling convention a C++ function uses, your best hope is to study
The header that declares that function, and
The documentation for the compiler that compiled your particular DLL.
But this whole thing sounds like a bit of a mess, honestly. Why does your friend want to be able to do this, and why can't he get the information he needs by parsing a header that declares the relevant functions?
This page describes the way VC++6 encodes parameter and calling convention info into a symbol name: http://www.bottledlight.com/docs/mangle.html
I suspect that later versions of VC++ will be compatible but I haven't confirmed this.
There are also some tools that automate this which accompany the compiler: http://msdn.microsoft.com/en-us/library/5x49w699.aspx
The name mangling only applies for C++ functions; if a function is 'extern "C"' then this won't work.