Python3 c api - python stops working - python-3.x

I was trying to get a list as an input. I've googled too.
I built and installed my C-extension module in the command prompt .I am able to import the module but it did show few warnings.What it had shown me was.....
At the CMD
D:\Python\c\summa>py setup.py build
running build
running build_ext
building 'saiyanism' extension
C:\Program Files\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.2612
8\bin\HostX86\x86\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IE:\python\include
-IE:\python\include "-IC:\Program Files\Microsoft Visual Studio\2017\Community\
VC\Tools\MSVC\14.13.26128\include" "-IC:\Program Files\Windows Kits\NETFXSDK\4.6
.1\include\um" "-IC:\Program Files\Windows Kits\10\include\10.0.16299.0\ucrt" "-
IC:\Program Files\Windows Kits\10\include\10.0.16299.0\shared" "-IC:\Program Fil
es\Windows Kits\10\include\10.0.16299.0\um" "-IC:\Program Files\Windows Kits\10\
include\10.0.16299.0\winrt" "-IC:\Program Files\Windows Kits\10\include\10.0.162
99.0\cppwinrt" /TcH.c /Fobuild\temp.win32-3.6\Release\H.obj
H.c
H.c(63): warning C4133: 'function': incompatible types - from 'PyObject *' to 'c
onst char *const '
H.c(117): warning C4113: 'PyObject *(__cdecl *)(PyObject *)' differs in paramete
r lists from 'PyCFunction'
C:\Program Files\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.2612
8\bin\HostX86\x86\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID
=2 /MANIFESTUAC:NO /LIBPATH:E:\python\libs /LIBPATH:E:\python\PCbuild\win32 "/LI
BPATH:C:\Program Files\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.1
3.26128\lib\x86" "/LIBPATH:C:\Program Files\Windows Kits\NETFXSDK\4.6.1\lib\um\x
86" "/LIBPATH:C:\Program Files\Windows Kits\10\lib\10.0.16299.0\ucrt\x86" "/LIBP
ATH:C:\Program Files\Windows Kits\10\lib\10.0.16299.0\um\x86" /EXPORT:PyInit_sai
yanism build\temp.win32-3.6\Release\H.obj /OUT:build\lib.win32-3.6\saiyanism.cp3
6-win32.pyd /IMPLIB:build\temp.win32-3.6\Release\saiyanism.cp36-win32.lib
Creating library build\temp.win32-3.6\Release\saiyanism.cp36-win32.lib and ob
ject build\temp.win32-3.6\Release\saiyanism.cp36-win32.exp
Generating code
d:\python\c\summa\h.c(112) : warning C4715: 'sumlist': not all control paths ret
urn a value
Finished generating code
D:\Python\c\summa>
Here is my c module....
H.c
#include "Python.h"
static PyObject* saiyanism(PyObject* self,PyObject* args)
{
const char* saiyajin;
if(!(PyArg_ParseTuple(args,"s",&saiyajin))) return NULL;
printf("Hello,%s.Glad to see a saiyan.\n",saiyajin);
Py_RETURN_NONE;
}
static PyObject* UI(PyObject* self) //,PyObject* args)
{/*code here works properly*/
Py_RETURN_NONE;
}
static PyObject* set_all(PyObject* self,PyObject *target)//PyLong_FromLong(PyObject *item))
{
/*some code and this too works*/
Py_RETURN_NONE;
}
static PyObject* sumlist(PyObject* self,PyObject *args)
{
PyObject *pList;
PyObject *pItem;
Py_ssize_t n;
int i;
if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &pList)) {
PyErr_SetString(PyExc_TypeError, "parameter must be a list.");
return NULL;
}
n = PyList_Size(pList);
for (i=0; i<n; i++) {
pItem = PyList_GetItem(pList, i);
if(!PyLong_Check(pItem)) {
PyErr_SetString(PyExc_TypeError, "list items must be integers.");
printf("%ld",PyLong_AsLong(pItem));
Py_RETURN_NONE;
}
}
}
static PyMethodDef sups[]=
{
{"saiyanism",saiyanism,METH_VARARGS,""},
{"UI",UI,METH_NOARGS,""},
{"set_all",set_all,METH_VARARGS,""},
{"sumlist",sumlist,METH_VARARGS,""},
{NULL,NULL,0,NULL}
};
static struct PyModuleDef saiyanismdef={
PyModuleDef_HEAD_INIT,
"saiyanism",
"sad",
-1,
sups
};
PyMODINIT_FUNC PyInit_saiyanism(void){
Py_Initialize();
return PyModule_Create(&saiyanismdef);
}
The problem is
when I try to import and run my sumlist function with a python list as parameter Python immediately stops .
Here is the image
I just started learning this, so if there are mistakes in my program please point them out.
Should I Pass the arguement in a different way?Where am I wrong?

I can see at least two mistakes in sumlist:
In the code
if(!PyLong_Check(pItem)) {
PyErr_SetString(PyExc_TypeError, "list items must be integers.");
printf("%ld",PyLong_AsLong(pItem));
Py_RETURN_NONE;
}
you return None (the Python object) rather than the C NULL pointer, which is used to signal an error. You also attempt to print pItem using PyLong_AsLong - the one thing you know about pItem here is that it is not a long!
(The main error that is causing you problems) What happens when you get to the end of sumlist without any errors? You do not return anything and Python is expecting you to return a PyObject*. This is what the warning is telling you:
warning C4715: 'sumlist': not all control paths return a value
A quick fix here would be to add Py_RETURN_NONE to the end of the function to return a None object to Python. However, you probably want to do something more useful....

Related

Getting error LNK2019: unresolved external symbol when compiling SDL2 code in Windows using MSVC

The complete error output:
SDL2main.lib(SDL_windows_main.obj) : error LNK2019: unresolved external symbol __imp_CommandLineToArgvW referenced in function main_getcmdline
My compiler options:
cl -D WINDOWS -nologo -W4 -WX -wd4100 -Fe"output_file.exe" input_file.c SDL2.lib SDL2main.lib -I ./SDL2-2.0.12/include -link -LIBPATH:./SDL2-2.0.12/lib/x64 -SUBSYSTEM:CONSOLE
My input_file.c header and main function:
#ifdef LINUX
#include <SDL2/SDL.h> /* Comes with stdio.h and stdlib.h */
#elif WINDOWS
#include <stdio.h>
#include "SDL.h"
#endif
int main(int argc, char* argv[]) {
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_TIMER) != 0)
{
fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError());
return -1;
}
. . .
The SDL development folder used in the command line arguments is the development libraries zip file downloaded from libsdl.org
Why am I getting this error?
you also need to use the library called "shell32.lib"
cl -D WINDOWS -nologo -W4 -WX -wd4100 -Fe"output_file.exe" input_file.c shell32.lib SDL2.lib SDL2main.lib -I ./SDL2-2.0.12/include -link -LIBPATH:./SDL2-2.0.12/lib/x64 -SUBSYSTEM:CONSOLE

Access a managed C++ lib from regular C++

I am trying to call a method in a managed C++ library from a regular (unmamanged) C++ file. I'm working from the example here (which is really good except for this little issue).
My managed C++ code is:
__declspec(dllexport) void ShowMessageBox(int *value)
{
AutoTagManagedBridge::Class1 work;
work.ShowCSharpMessageBox(value);
}
My unmanaged C++ code is:
_declspec(dllexport) void ShowMessageBox(int *value);
// ...
ACCB1 void ACCB2 MyPluginCommand(void *clientData)
{
int val = 5;
int *result = &val;
ShowMessageBox(result);
// ...
In the unmanaged C++ project, I set the managed C++ project as a reference. However, when I compile I get:
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "void __cdecl
ShowMessageBox(int *)" (?ShowMessageBox##YAXPAH#Z) referenced in
function "void __cdecl MyPluginCommand(void *)"
(?MyPluginCommand##YAXPAX#Z) BasicPlugin C:\src\AdobePlugin\win32\BasicPlugin.obj 1
And when I look at the link command the managed C++ module (AutoTagManagedBridge.lib) is not listed:
/OUT:"Debug/BasicPlugin.api" /MANIFEST /NXCOMPAT
/PDB:".\Debug/BasicPlugin.pdb" /DYNAMICBASE "odbc32.lib"
"odbccp32.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib"
"comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib"
"uuid.lib" /IMPLIB:".\Debug/BasicPlugin.lib" /DEBUG /DLL /MACHINE:X86
/SAFESEH /INCREMENTAL /PGD:".\Debug\BasicPlugin.pgd"
/SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/ManifestFile:".\Debug\BasicPlugin.api.intermediate.manifest"
/ERRORREPORT:PROMPT /NOLOGO /TLBID:1
What else do I need to do?
Found the answer. In order for VisualStudio to recognize a .lib file from the Managed C++, you need to set on your UnManaged project right click and Properties -> ConfigurationProperties -> Linker -> Input ->
Additional Dependencies - > "$(SolutionDir)$(Configuration)\ManagedDll.lib".

I can't compile telegram source code with NDK

I installed NDK and set the NDK path in "Project Structure" :
And then I added below codes to build.gradle:
task buildNative(type: Exec, description: 'Compile JNI source via NDK')
{
def ndkDir = android.ndkDirectory
commandLine "$ndkDir/ndk-build.cmd",
'-C', file('jni').absolutePath, // Change src/main/jni the relative path to your jni source
'-j', Runtime.runtime.availableProcessors(),
'all',
'NDK_DEBUG=1'
}
task cleanNative(type: Exec, description: 'Clean JNI object files') {
def ndkDir = android.ndkDirectory
commandLine "$ndkDir/ndk-build.cmd",
'-C', file('jni').absolutePath, // Change src/main/jni the relative path to your jni source
'clean'
}
clean.dependsOn 'cleanNative'
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn buildNative
}
And add this code to "defauilConfig" in build.gradle :
ndk {
moduleName "TMessagesProj"
}
When I try to build an APK , I get this error :
Error:Execution failed for task ':TMessagesProj:buildNative'.
Process 'command 'C:\Users\Mehran\AppData\Local\Android\ndk\android-ndk-r12/ndk-build.cmd'' finished with non-zero exit value 2
This is the Messages Console :
make (e=2): The system cannot find the file specified.
make: *** [D:/Mehran/AndroidStudioProjects/TelegramTest/TMessagesProj/obj/local/armeabi/objs-debug/tmessages.22/./opus/src/opus_encoder.o] Error 2
make: Leaving directory `D:/Mehran/AndroidStudioProjects/TelegramTest/TMessagesProj/jni'
Sorry for my bad English.

Android NDK - Android studio gradle undefined reference to __android_log_write

I am trying to debug a JNI C function by inserting log messages, but I can't get it to work. To start with I am just trying to modify the hello-jni example that comes with Android Studio. This is the modified code:
#include <string.h>
#include <jni.h>
#include <android/log.h>
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#if defined(__ARM_PCS_VFP)
#define ABI "armeabi-v7a/NEON (hard-float)"
#else
#define ABI "armeabi-v7a/NEON"
#endif
#else
#if defined(__ARM_PCS_VFP)
#define ABI "armeabi-v7a (hard-float)"
#else
#define ABI "armeabi-v7a"
#endif
#endif
#else
#define ABI "armeabi"
#endif
#elif defined(__i386__)
#define ABI "x86"
#elif defined(__x86_64__)
#define ABI "x86_64"
#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */
#define ABI "mips64"
#elif defined(__mips__)
#define ABI "mips"
#elif defined(__aarch64__)
#define ABI "arm64-v8a"
#else
#define ABI "unknown"
#endif
__android_log_write(ANDROID_LOG_ERROR, "TEST_TAG", "Error here");
return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");
}
And this is my Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
LOCAL_LDFLAGS := -llog
include $(BUILD_SHARED_LIBRARY)
When I use the ndk-build script the libhello-jni.so files get built no problem. When I try to build the project in Android Studio I get the following gradle error message
Information:Gradle tasks [:app:assembleDebug]
:app:preBuild
:app:compileDebugNdk
C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\obj/local/arm64-v8a/objs/hello-jni/C_\Android\projects\hello-jni\app\src\main\jni\hello-jni.o: In function `Java_com_example_hellojni_HelloJni_stringFromJNI':
hello-jni.c:(.text.Java_com_example_hellojni_HelloJni_stringFromJNI+0x24): undefined reference to `__android_log_write'
Error:error: ld returned 1 exit status
make.exe: *** [C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\obj/local/arm64-v8a/libhello-jni.so] Error 1
Error:Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.internal.LoggedErrorException: Failed to run command:
C:\Android\android-ndk-r10c\ndk-build.cmd NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\Android.mk APP_PLATFORM=android-19 NDK_OUT=C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\obj NDK_LIBS_OUT=C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\lib APP_ABI=all
Error Code:
2
Output:
C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\obj/local/arm64-v8a/objs/hello-jni/C_\Android\projects\hello-jni\app\src\main\jni\hello-jni.o: In function `Java_com_example_hellojni_HelloJni_stringFromJNI':
hello-jni.c:(.text.Java_com_example_hellojni_HelloJni_stringFromJNI+0x24): undefined reference to `__android_log_write'
collect2.exe: error: ld returned 1 exit status
make.exe: *** [C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\obj/local/arm64-v8a/libhello-jni.so] Error 1
Information:BUILD FAILED
Information:Total time: 3.297 secs
Information:2 errors
Information:0 warnings
Information:See complete output in console
I've tried the suggestions given in this question, but I still get the same error: What is the Log API to call from an Android JNI program?
What am I doing wrong?
I'm using Android Studio 0.8.9 and NDK r10c.
I found an answer after a bit more searching.
If I build the .so files using the ndk-build script on the command line and add
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
into my build.gradle file so gradle doesn't try to build the .so files it all then works. Looks like a problem with Android Studio-Gradle-NDK integration?
I found the answer here https://stackoverflow.com/a/21111458/4182796
Ugly workaround is to remove function call and rebuild sources just add this after includes :
#if 1
#undef __android_log_print
#define __android_log_print(...) {}
#endif

Export struct defined in winbase.h with ATL's IDL

This is my method defined in IDL:
[id(3), helpstring("method GetBatteryStatus")]
HRESULT GetBatteryStatus([out,retval] SYSTEM_POWER_STATUS_EX2* batteryStatus);
The SYSTEM_POWER_STATUS_EX2 is a struct defined in winbase.h, and this project is a ATLSmartPhone Project, the winbase.h is from Microsoft's SDK.
When I compile the project the error are :
error MIDL2025 : syntax error : expecting a type specification near "SYSTEM_POWER_STATUS_EX2"
If I add import "winbase.h" to the top of the IDL file, the error will be:
error MIDL2003 : redefinition : size_t; error MIDL2003 : redefinition : _LARGE_INTEGER;.....
Then if I add the typedef in in IDL:
typedef[public,uuid(37DE998A-6787-415a-A191-861C315D1248),helpstring("Power Status")]
struct _SYSTEM_POWER_STATUS_EX2 {
...
...
} SYSTEM_POWER_STATUS_EX2;
The error will be:
error C2011: '_SYSTEM_POWER_STATUS_EX2' : 'struct' type redefinition.
So how can I export the SYSTEM_POWER_STATUS_EX2 struct which was defined in winbase.h with IDL?
You can write the IDL version of the SYSTEM_POWER_STATUS_EX2 in the separate IDL file and import it for MIDL only:
cpp_quote("#if 0")
import "fake.idl";
cpp_quote("#else")
cpp_quote("#include <orginial_header>")
cpp_quote("#endif")

Resources