getting depreciation warning in OpenSSL - c

This is a simple program which generates MD5 digest of a file and compares with the predefined MD5 digest in a program and checks for its integrity.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <openssl/md5.h>
char * calculate_file_md5(const char *filename)
{
unsigned char c[MD5_DIGEST_LENGTH];
int i;
MD5_CTX mdContext;
int bytes;
unsigned char data[1024];
char *filemd5 = (char*) malloc(33 *sizeof(char));
FILE *inFile = fopen (filename, "rb");
if (inFile == NULL) {
perror(filename);
return 0;
}
MD5_Init (&mdContext);
while ((bytes = fread (data, 1, 1024, inFile)) != 0)
MD5_Update (&mdContext, data, bytes);
MD5_Final (c,&mdContext);
for(i = 0; i < MD5_DIGEST_LENGTH; i++) {
sprintf(&filemd5[i*2], "%02x", (unsigned int)c[i]);
}
printf("calculated md5:%s ", filemd5);
printf (" %s\n", filename);
fclose (inFile);
return filemd5;
}
int main(int argc, char **argv) {
char * predefined_md5 = "8e2745d333daa9666a8bbebcd32a39bb";
char *new_md5 = calculate_file_md5("backup.json");
if (!strcmp(predefined_md5, new_md5)) {
printf("md5 matched\n");
} else {
printf("md5 not matched\n");
}
free(new_md5);
return 0;
}
Program compiled and run gracefully but can any one tell me to sort the following warnings
GenerateMD5Hash.c: In function ‘calculate_file_md5’:
GenerateMD5Hash.c:18:9: warning: ‘MD5_Init’ is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
18 | MD5_Init (&mdContext);
| ^~~~~~~~
In file included from headers.h:5,
from GenerateMD5Hash.c:1:
/usr/include/openssl/md5.h:49:27: note: declared here
49 | OSSL_DEPRECATEDIN_3_0 int MD5_Init(MD5_CTX *c);
| ^~~~~~~~
GenerateMD5Hash.c:22:9: warning: ‘MD5_Update’ is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
22 | MD5_Update (&mdContext, data, bytes);
| ^~~~~~~~~~
In file included from headers.h:5,
from GenerateMD5Hash.c:1:
/usr/include/openssl/md5.h:50:27: note: declared here
50 | OSSL_DEPRECATEDIN_3_0 int MD5_Update(MD5_CTX *c, const void *data, size_t len);
| ^~~~~~~~~~
GenerateMD5Hash.c:24:9: warning: ‘MD5_Final’ is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
24 | MD5_Final (c,&mdContext);
| ^~~~~~~~~
In file included from headers.h:5,
from GenerateMD5Hash.c:1:
/usr/include/openssl/md5.h:51:27: note: declared here
51 | OSSL_DEPRECATEDIN_3_0 int MD5_Final(unsigned char *md, MD5_CTX *c);
using ubuntu mate OS
command used to compile
gcc GenerateMD5Hash.c -lcrypto -o GenerateMD5Hash

From OpenSSL:
The following functions have been deprecated since OpenSSL 3.0, and
can be hidden entirely by defining OPENSSL_API_COMPAT with a suitable
version value, see openssl_user_macros(7):
unsigned char *MD5(const unsigned char *d, unsigned long n, unsigned char *md);
int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data, unsigned long len);
int MD5_Final(unsigned char *md, MD5_CTX *c);
All of the functions described on this page are deprecated.
Applications should instead use
EVP_DigestInit_ex(3),
EVP_DigestUpdate(3) and
EVP_DigestFinal_ex(3).
They are there for backwards compatibility. If you wish to ignore the warnings, you could:
Just ignore them.
Redirect the output to /dev/null.
Use the functions they recommend instead.

Related

C Pointer Error

The program below is supposed to read a txt file and put the data in a struct. But it gives an pointer error. It gives an error in strcpy() about pointers. I'm new in C. Whats wrong?
#include <stdio.h>
#include <string.h>
int main()
{
struct citydata {
char city[20];
int temp;
};
struct citydata values[15];
struct citydata Avg;
struct citydata high;
struct citydata low;
FILE* inp;
int reccount = 0;
int x = 0;
char s;
int n;
inp = fopen("mydata.txt", "r");
if (!inp) {
printf("Unable ot open file\n");
}
while (fscanf(inp, "%s %d", s, &n) != EOF) {
strcpy(values[x].city, s);
values[x].temp = n;
x++;
}
fclose(inp);
}
Don't ignore compiler warnings.
When if you compile this code (say, with gcc), you get the following warnings:
test.c:27:24: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=]
while (fscanf(inp, "%s %d", s, &n) != EOF) {
^
test.c:28:32: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy(values[x].city, s);
^
In file included from test.c:2:0:
/usr/include/string.h:125:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
so, as comments suggest, you can't scan directly into the struct; you can only scan into simpler types the C standard libraries recognizes: integer, floating-point numbers, char * strings etc. Similarly, you can't perform a string copy from your structs, which are not strings.
C is a strongly-typed language with very few allowed implicit conversions. In some cases, you are able to pass integers instead of floats or vice-versa, but nothing "magically converts" into a string, or is "magically parsed" from a string.
... and there are other issues:
Note #EdHeal 's comment: If your fopen() fails, you mustn't continue running the rest of the code. Either you should exit(EXIT_FAILURE); or wrap the rest of the code in main() within an else() block.
You should printf error messages to the standard error stream, so instead of printf("error message here") it should fprintf(stderr,"error message here"). Also, the standard C library places an error code you can get as the errno variable, or you can have an error message printed to the standard error stream with the perror() function. There are a few other related related functions (like strerror(), `err() etc.) which I will not get into here.
make some mistakes with pointers=)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct citydata
{
char *city;
int temp;
} citydata;
int main()
{
char *s;
citydata *values;
values = (citydata*)malloc(sizeof(citydata) * 16);
FILE * inp;
int reccount = 0;
int x = 0;
int n;
inp = fopen("mydata.txt", "r");
if(!inp)
printf("Unable ot open file\n");
while (fscanf(inp,"%s %d",s, &n) != EOF)
{
values[x].city = (char*)malloc(sizeof(char) * 20);
strcpy(values[x].city, s);
values[x].temp = n;
x++;
}
fclose(inp);
}

Undefined reference when compiling a C file with a relative path header included

I cannot compile a C file that contain a function-call of a function, which is in another file. The compilation gives an error which says that there is an undefined reference even if I included the relative path to the Header file in the compilated file.
#include <stdio.h>
#include "../libft.h"
void *ft_memmove(void *dest, const void *src, size_t n)
{
unsigned char *d;
unsigned char *s;
size_t i;
d = (unsigned char *)dest;
s = (unsigned char *)src;
i = 0;
if (s < d)
{
while (n--)
d[n] = s[n];
}
else
ft_memcpy(d, s, n);
return (d);
}
int main()
{
char str[] = "memmove can be very useful.....";
ft_memmove (str+20, str+15, 11);
puts (str);
return (0);
}
The error that I get : gcc complier error
The header file : the header file
Can you help me please to resolve this problem ?

Segmentation fault around MD5 code

While I am running this md5 code, it is taking maximum 64 characters length of input at run time. Whenever I am giving more than 64 characters, it is showing
Inconsistency detected by ld.so: dl-fini.c: 205: _dl_fini: Assertion ns != 0 || i == nloaded failed!
I need to hash nearly 10kb of input (only string). Do I need to change anything in the header file? Can anyone tell me solution please?
md5.h
#ifndef HEADER_MD5_H
#define HEADER_MD5_H
#include <openssl/e_os2.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef OPENSSL_NO_MD5
#error MD5 is disabled.
#endif
/*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* ! MD5_LONG has to be at least 32 bits wide. If it's wider, then !
* ! MD5_LONG_LOG2 has to be defined along. !
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*/
#if defined(__LP64__)
#define MD5_LONG unsigned long
#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
#define MD5_LONG unsigned long
#define MD5_LONG_LOG2 3
/*
* _CRAY note. I could declare short, but I have no idea what impact
* does it have on performance on none-T3E machines. I could declare
* int, but at least on C90 sizeof(int) can be chosen at compile time.
* So I've chosen long...
* <appro#fy.chalmers.se>
*/
#else
#define MD5_LONG unsigned long
#endif
#define MD5_CBLOCK 64
#define MD5_LBLOCK (MD5_CBLOCK/2)
#define MD5_DIGEST_LENGTH 16
typedef struct MD5state_st
{
MD5_LONG A,B,C,D;
MD5_LONG Nl,Nh;
MD5_LONG data[MD5_LBLOCK];
unsigned int num;
} MD5_CTX;
#ifdef OPENSSL_FIPS
int private_MD5_Init(MD5_CTX *c);
#endif
int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
int MD5_Final(unsigned char *md, MD5_CTX *c);
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
void MD5_Transform(MD5_CTX *c, const unsigned char *b);
#ifdef __cplusplus
}
#endif
#endif
md5.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "md5.h"
char *pt(char *, int );
int main(int argc, char **argv)
{
char *in;
char *out;
printf("ENter the string\n");
scanf("%[^\n]s",in);
size_t len; //unsigned long len; size_t len;
len = printf("len is %d\n",strlen(in));
out = pt(in, len);
printf("MD5 is\t: %s\n", out);
free(out);
//return 0;
}
char *pt(char *str, int length)
{
int n;
MD5_CTX c;
unsigned char digest[16];
char *output = (char*)malloc(33);
MD5_Init(&c);
MD5_Update(&c, str, length);
MD5_Final(digest, &c);
for (n = 0; n < 16; ++n)
{
sprintf(&output[n*2], "%02x", (unsigned int)digest[n]);
}
return output;
}
Problem 1
For this statement:
scanf("%[^\n]s",in);
When I compile it using the -Wall flag, I get the warning:
warning: 'in' is used uninitialized in this function [-Wuninitialized]
scanf("%[^\n]s",in);
^
As you see, in is not pointing to any location in your memory, so you first need to allocate some memory either with an array or malloc():
char in[500]; //or a higher value
char *out;
printf("Enter the string\n");
scanf("%499[^\n]s", in);
printf("\nin = .%s.\n", in);
or
char *in;
char *out;
in = malloc(500); //or a higher value
printf("Enter the string\n");
scanf("%499[^\n]s", in);
printf("\nin = .%s.\n", in);
Possible problem 2
You are assigning the return from printf() to the variable len.
len = printf("len is %d\n",strlen(in));
Return value printf:
Upon successful return, it returns the number of characters printed (excluding the null byte used to end output to strings).
Assuming you want the variable len to contain the length of the string in and not the number of characters printed by printf("len is %d\n",strlen(in)), you might want to assign the return from strlen() first:
len = strlen(in);
printf("len is %d\n", len);

C program issues with function prototype

i am reading the C program book written by Denis and i was practicing his examples. I tried this example on my own and then copy pasted the same example from book. I get the followin error.
Code :
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line size */
int getline(char line[], int maxline);
void copy(char to[], char from[]);
/* print longest input line */
main()
{
int len; /* current line length */
int max; /* maximum length seen so far */
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
max = 0;
while ((len = getline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0) /* there was a line */
printf("%s", longest);
return 0;
}
/* getline: read a line into s, return length */
int getline(char s[], int lim)
{
int c, i;
for (i=0; i<lim-1 && (c=getchar())!=EOF && c!=′\n′; ++i)
s[i] = c;
if (c == ′\n′) {
s[i] = c;
++i;
}
s[i] = ′\0′;
return i;
}
/* copy: copy ′from′ into ′to′; assume to is big enough */
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != ′\0′)
++i;
}
Error:
ex16.c:4:5: error: conflicting types for 'getline'
int getline(char line[], int maxline);
^
/usr/include/stdio.h:440:9: note: previous declaration is here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_...
^
ex16.c:8:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
main()
^~~~
ex16.c:16:40: error: too few arguments to function call, expected 3, have 2
while ((len = getline(line, MAXLINE)) > 0)
~~~~~~~ ^
/usr/include/stdio.h:440:1: note: 'getline' declared here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_...
^
ex16.c:27:5: error: conflicting types for 'getline'
int getline(char s[], int lim)
^
/usr/include/stdio.h:440:9: note: previous declaration is here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_...
^
1 warning and 3 errors generated.
I am using function prototype correctly only i guess. Refered other internet sources also. I am not sure if its because of compiler. I am using Gcc version 4.3 i guess. OS - mac maverics.
Can you please help me ?
Thanks.
Just call your function getlineMy() in the places where you declare, define and use it.
getline() is already declared in stdio.h (link) and its implementation will be linked to your program so you cannot use that name unless you do tricks.
You have to set GCC to compile your code as C.
gcc -std=c99 -pedantic-errors -Wall
You will then get one error:
8:1: error: return type defaults to 'int'
This is because you are using the wrong definition for main(). Correct it to int main().
The name getline is just fine to use, there is no such function in stdio.h and the compiler is not allowed to add functions that are non-standard extensions inside that header, without naming them with a _ prefix.

How do you use the python3 c api for a command line driven app?

I've been using a custom build as a replacement for virtualenv for a while now, and it's brillant. It takes longer to build, but it actually works, and it never screws up.
Part of this in a simple python wrapper that adds some specific folders to the library path, which I've found very useful. The code for it is trivial:
#include <stdio.h>
#include <n/text/StringUtils.h>
#include <Python.h>
int main(int argc, char *argv[]) {
/* Setup */
Py_SetProgramName(argv[0]);
Py_Initialize();
PySys_SetArgv(argc, argv);
/* Add local path */
PyObject *sys = PyImport_ImportModule("sys");
PyObject *path = PyObject_GetAttrString(sys, "path");
/* Custom path */
char *cwd = nrealpath(argv[0]);
char *libdir = nstrpath(cwd, "python_lib", NULL);
PyList_Append(path, PyString_FromString(libdir));
free(cwd);
free(libdir);
/* Run the 'main' module */
int rtn = Py_Main(argc, argv); // <-- Notice the command line arguments.
Py_Finalize();
return rtn;
}
So, moving to python3 is good right? So...
I dutifully replaced the call to PyString_FromString() with PyByte_FromString() and tried to recompile, but it raises errors:
/Users/doug/env/src/main.c:8:21: error: incompatible pointer types passing 'char *' to parameter of type 'wchar_t *' (aka 'int *')
[-Werror,-Wincompatible-pointer-types]
Py_SetProgramName(argv[0]);
^~~~~~~
/Users/doug/projects/py-sdl2/py3/include/python3.3m/pythonrun.h:25:45: note: passing argument to parameter here
PyAPI_FUNC(void) Py_SetProgramName(wchar_t *);
^
/Users/doug/env/src/main.c:10:23: error: incompatible pointer types passing 'char **' to parameter of type 'wchar_t **' (aka 'int **')
[-Werror,-Wincompatible-pointer-types]
PySys_SetArgv(argc, argv);
^~~~
/Users/doug/projects/py-sdl2/py3/include/python3.3m/sysmodule.h:12:47: note: passing argument to parameter here
PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **);
^
/Users/doug/env/src/main.c:24:27: error: incompatible pointer types passing 'char **' to parameter of type 'wchar_t **' (aka 'int **')
[-Werror,-Wincompatible-pointer-types]
int rtn = Py_Main(argc, argv);
^~~~
/Users/doug/projects/py-sdl2/py3/include/python3.3m/pythonrun.h:148:45: note: passing argument to parameter 'argv' here
PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv);
^
3 errors generated.
make[2]: *** [CMakeFiles/python.dir/src/main.c.o] Error 1
make[1]: *** [CMakeFiles/python.dir/all] Error 2
make: *** [all] Error 2
As you can see from the error, wchar_t is used instead of char *.
How are you supposed to use this api?
I see there are a few examples of doing this, for example:
http://svn.python.org/projects/python/tags/r32rc2/Python/frozenmain.c
seriously?
My 29 line program has to become a 110 line monster full of #ifdefs?
Am I misunderstanding, or has the python3 c api really become this ridiculously difficult to use?
Surely I'm missing some obvious convenience function which does this for you, in a simple, portable and cross platform way?
The official recommended way of converting from char to wchar_t is by using Py_DecodeLocale. Like this:
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
Py_SetProgramName(program);
I spent a lot of time looking for the answer myself. I pieced together comments from other people, and built this snippet to convert char** argv to type wchar_t**:
wchar_t** _argv = PyMem_Malloc(sizeof(wchar_t*)*argc);
for (int i=0; i<argc; i++) {
wchar_t* arg = Py_DecodeLocale(argv[i], NULL);
_argv[i] = arg;
}
Py_Initialize();
PySys_SetArgv(argc, _argv);
So far, it works great. I've confirmed that the command line arguments are being received correctly by my embedded Python code.
Seems there's no easy way to do this.
The closest I've come to below. I'll leave the question open in the vague hopes someone will come along and show me the super easy and simple way to do this.
#include <stdio.h>
#include <Python.h>
#include <wchar.h>
int main(int argc, char *argv[]) {
/* These have to be wchar_t */
char *str_program_name = argv[0];
char **str_argv = argv;
/* For ever stupid reason, these don't need to be wchar_t * */
char *_sys = "sys";
char *_libdir = "lib";
char *_path = "path";
char *_dot = ".";
#if PY_MAJOR_VERSION >= 3
wchar_t **_argv = nstrws_array(argc, str_argv);
wchar_t *_program_name = nstrws_convert(str_program_name);
#else
char **_argv = str_argv;
char *_program_name = str_program_name;
#endif
/* Setup */
Py_SetProgramName(_program_name);
Py_Initialize();
/* Add local path */
#if PY_MAJOR_VERSION >= 3
PyObject *sys = PyImport_ImportModule(_sys);
PyObject *path = PyObject_GetAttrString(sys, _path);
PyList_Append(path, PyBytes_FromString(_dot));
PyList_Append(path, PyBytes_FromString(_libdir));
#else
PyObject *sys = PyImport_ImportModule(_sys);
PyObject *path = PyObject_GetAttrString(sys, _path);
PyList_Append(path, PyString_FromString(_dot));
PyList_Append(path, PyString_FromString(_libdir));
#endif
/* Run the 'main' module */
int rtn = Py_Main(argc, _argv);
Py_Finalize();
#if PY_MAJOR_VERSION >= 3
nstrws_dispose(argc, _argv);
free(_program_name);
#endif
return rtn;
}
Using:
/** Unix-like platform char * to wchar_t conversion. */
wchar_t *nstrws_convert(char *raw) {
wchar_t *rtn = (wchar_t *) calloc(1, (sizeof(wchar_t) * (strlen(raw) + 1)));
setlocale(LC_ALL,"en_US.UTF-8"); // Unless you do this python 3 crashes.
mbstowcs(rtn, raw, strlen(raw));
return rtn;
}
/** Dispose of an array of wchar_t * */
void nstrws_dispose(int count, wchar_t ** values) {
for (int i = 0; i < count; i++) {
free(values[i]);
}
free(values);
}
/** Convert an array of strings to wchar_t * all at once. */
wchar_t **nstrws_array(int argc, char *argv[]) {
wchar_t **rtn = (wchar_t **) calloc(argc, sizeof(wchar_t *));
for (int i = 0; i < argc; i++) {
rtn[i] = nstrws_convert(argv[i]);
}
return rtn;
}
and for windows users, if required:
#include <windows.h>
/** Windows char * to wchar_t conversion. */
wchar_t *nstrws_convert(char *raw) {
int size_needed = MultiByteToWideChar(CP_UTF8, 0, raw, -1, NULL, 0);
wchar_t *rtn = (wchar_t *) calloc(1, size_needed * sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, raw, -1, rtn, size_needed);
return rtn;
}
The following code contains C++ implementation of Hello World embedding Python.
HelloWorld.cpp:
#include <cstdlib>
#include <stdexcept>
#include <Python.h>
int main(int argc, char* argv[])
{
wchar_t** wargv = new wchar_t*[argc];
for(int i = 0; i < argc; i++)
{
wargv[i] = Py_DecodeLocale(argv[i], nullptr);
if(wargv[i] == nullptr)
{
return EXIT_FAILURE;
}
}
Py_SetProgramName(wargv[0]);
Py_Initialize();
PySys_SetArgv(argc, wargv);
PyRun_SimpleString("import sys");
PyRun_SimpleString("print('Hello World!', sys.argv)");
Py_Finalize();
for(int i = 0; i < argc; i++)
{
PyMem_RawFree(wargv[i]);
wargv[i] = nullptr;
}
delete[] wargv;
wargv = nullptr;
return 0;
}
Install Prerequisites for Compilation*:
$ sudo apt install build-essential pkg-config python3 python3-dev
Compiling the Source Code:
$ g++ HelloWorld.cpp `pkg-config python3-embed --libs --cflags` -o HelloWorld
Run:
$ ./HelloWorld
$ # Hello World! ['./HelloWorld']
$
$ ./HelloWorld hi
$ # Hello World! ['./HelloWorld', 'hi']
I've found that this works at converting the char* to wchar_t* in the main function:
wchar_t progname[FILENAME_MAX + 1];
mbstowcs(progname, argv[0], strlen(argv[0]) + 1);
Py_SetProgramName(progname);
If you are on unix use:
#include "sys/param.h"
Py_DecodeLocale Return a pointer to a newly allocated wide character string, use PyMem_RawFree() to free the memory. So there is no need to define wchar_t** _argv = PyMem_Malloc(sizeof(wchar_t*)*argc);
bellow is my code:
#include <iostream>
#include <string>
#include "hello-time.h"
#include "main/hello-greet.h"
#include "pybind11/embed.h"
namespace py = pybind11;
int main(int argc, char** argv) {
std::string who = "world";
if (argc > 1) {
who = argv[1];
}
std::cout << get_greet(who) << std::endl;
print_localtime();
int py_argc = 9;
py::scoped_interpreter guard{};
wchar_t* wargv[py_argc];
std::string py_argv[py_argc] = {"convert.py",
"--input",
"resnet_v1_50_inference.pb",
"--inputs",
"input:0",
"--outputs",
"resnet_v1_50/predictions/Reshape_1:0",
"--output",
"resnet50.onnx"};
for (int i = 0; i < py_argc; i++) {
wargv[i] = Py_DecodeLocale(py_argv[i].c_str(), nullptr);
if (wargv[i] == nullptr) {
fprintf(stderr, "Fatal error: cannot decode py_argv[%d]\n", i);
exit(1);
}
}
PySys_SetArgv(py_argc, wargv);
py::module_ sys = py::module_::import("sys");
py::print(sys.attr("path"));
print_localtime();
py::object convert = py::module_::import("tf2onnx.convert");
py::object do_convert = convert.attr("main");
do_convert();
py::print(py::module::import("sys").attr("argv"));
for (int i = 0; i < py_argc; i++) {
PyMem_RawFree(wargv[i]);
wargv[i] = nullptr;
}
return 0;
}
This is probably the wrong way to do it, never the less:
Py_SetProgramName((wchar_t*)argv[0]);
This fix stopped my code from complaining, haven't tested it to know how it handles args, but at least it compiles..

Resources