Why this redundancy in Swig interface file? - swig

I see here that the swig interface file has identical declarations at 2 places (in and after %{ }% part).
/* example.i */
%module example
%{
/* Put header files here or function declarations like below */
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
%}
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
Why is this redundancy needed?

The code between %{ and %} is directly injected in the generated SWIG wrapper code to make the declarations available to the compiler. For example you could have a utility function in this block that's only visible to the compiler but not exposed to the target language, or add #include statements needed to compile the wrapper.
Code outside that block is parsed by SWIG and exposed to the target language. If you left out one of the declarations in this section it wouldn't be exposed to the target language.
You can eliminate the redundancy in this case by using %inline, which both injects the code into the wrapper and parses it for exposure to the target language:
%module example
%inline %{
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
%}

Related

How to skip SWIG directives in clang-format

We use SWIG to generate Python wrappers for some C++ code. SWIG directives start with %, and look like this in headers:
#ifdef SWIG
%apply int* INT_RET_VAL{int * is_donor};
#ENDIF
ErrLevel mmct_hbond_is_donor(MM_Index ct, int atom_idx, int* is_donor);
#ifdef SWIG
%clear int * is_donor;
#ENDIF
When clang-format processes them, the %apply turns to % apply, which is not a SWIG statement anymore! There are lots of these in our code base currently. Is there a good way to convince clang-format to skip the %apply and %clear statements? Or maybe everything in an #ifdef SWIG?
You can use // clang-format off.
int formatted_code;
// clang-format off
void unformatted_code ;
// clang-format on
void formatted_code_again;
https://clang.llvm.org/docs/ClangFormatStyleOptions.html#disabling-formatting-on-a-piece-of-code

with emacs,I can't export source code in org file to html in highlight mode

I have taken htmlize in use, here is the configuration
(add-to-list 'load-path
"~/.emacs.d/plugins/")
(require 'htmlize)
(setq org-src-fontify-natively t)
(setq org-export-with-sub-superscripts nil)
with this configuation, After I export the org file below: I get the output like the picture at the bottom of this page.
#+STYLE: <style> pre.src { background-color:#1e3436; color: #eeeeec;}</style>
*tst code
#+BEGIN_SRC c
extern struct list_head llc_sap_list;
int a = 0;
#+END_SRC
#+begin_src c
#define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */
#define LLC_DEST_SAP 1 /* Type 1 goes here */
#define LLC_DEST_CONN 2 /* Type 2 goes here */
extern spinlock_t llc_sap_list_lock;
extern int llc_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev);
extern int llc_mac_hdr_init(struct sk_buff *skb,
const unsigned char *sa, const unsigned char *da);
extern void llc_add_pack(int type, void (*handler)(struct llc_sap *sap,
struct sk_buff *skb));
extern void llc_remove_pack(int type);
extern void llc_set_station_handler(void (*handler)(struct sk_buff *skb));
extern struct llc_sap *llc_sap_open(unsigned char lsap,
int (*rcv)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt,
struct net_device *orig_dev));
static inline void llc_sap_hold(struct llc_sap *sap)
{
atomic_inc(&sap->refcnt);
}
extern void llc_sap_close(struct llc_sap *sap);
#+end_src
the output html, the color of the code is all in gray.
I can't upload it, but this problem really blocked me, in this whole night. thanks for your help on this.
Why are you setting this?
(setq org-src-fontify-natively t)
I think you want the opposite (which is the default). Try setting it to nil and htmlize should kick in.
In fact, I don't think you even need the
(require 'htmlize)
I have it installed from ELPA, so maybe that set up the autoload, but I don't have any reference to htmlize in my .emacs and it "just works."

cuModuleGetFunction don't accepts simple kernel names, only ".entry"-tags from .ptx-file

I convert my .cu-files using CUDA_COMPILE_PTX from findPackageCUDA.cmake. When I try to get the function-pointers to my kernels I am facing the following problem:
My kernel named Kernel1 only can be loaded correctly via cuModuleGetFunction if I use its .entry-label from the resulting .ptx-file, e.g. _Z7Kernel1Pj
The problem is that this label may change each time I have to recompile my .cu-files. This can't be a solution if I reference them by name in a constant char*.
_Z7Kernel1Pj is a C++ mangled name. If you want to have a simple symbol you can use extern "C"
extern "C" void Kernel1(...)
For example if you use the default CUDA visual studio project contains the kernel
__global__ void addKernel(int *c, const int *a, const int *b)
If you run cuobjdump -symbols on this you will see the mangled symbol name
STT_FUNC STB_GLOBAL _Z9addKernelPiPKiS1_
If you use extern "C"
extern "C" __global__ void addKernel(int *c, const int *a, const int *b)
the symbol name will now be
STT_FUNC STB_GLOBAL addKernel
Using extern "C" will result in loss of function overloading and namespaces

Use SWIG to apply multiple Java data types for same C data type

I have two C functions that I'm exposing through SWIG to my Java layer and both have an input param with a const void * data type ("val) that needs to be a uint8_t for the addCategory function but a char for the addAttribute function. I'm currently, in the SWIG Interface file, using the %apply to map the const void * C type to a short on the Java side. Is there a way to modify the SWIG interface file to support both a char (String) and a uint8_t (short) for the const void * input parameter?
C Functions from header file:
int
addCategory(query_t *query, type_t type, const void *val);
int
addAttribute(query_t *query, type_t type, const void *val);
SWIG Interface File:
%module Example
%include "stdint.i"
void setPhy_idx(uint32_t value);
%include "arrays_java.i"
void setId(unsigned char *value);
%{
#include "Example.h"
%}
%apply char * { unsigned char * };
%apply char * { void * };
%apply uint8_t { const void * }
%apply int32_t { int32_t * }
%include "Example.h"
You can't directly do this - what type would be used in this place in Java? You need to help SWIG decide that in some way.
You have (at least) three possible solutions:
Use a type hierarchy - The base type will be what the function takes, the subclasses will get wrapped also. You could do this on the C++ side, or on the Java side using SWIG's typemap facilities. I think this is needlessly complicated though, so I've not made an example here.
Use overloads (or even different functions, with different names altogether - you could use %rename to make them back into overloads in Java even if they have different names in C)
Use a union. This will get wrapped with set and get functions by SWIG:
%module test
union values {
unsigned char *string;
void *generic;
uint8_t someOtherThing;
uint32_t number;
};
void func(values v);
This results in a Java class called values, which func() takes and can pass one of the members of the union through. Clearly you'd want to %apply appropriate typemaps for the members of the union.

C++: Explicit DLL Loading: First-chance Exception on non "extern C" functions

I am having trouble importing my C++ functions. If I declare them as C functions I can successfully import them. When explicit loading, if any of the functions are missing the extern as C decoration I get a the following exception:
First-chance exception at 0x00000000 in cpp.exe: 0xC0000005: Access violation.
DLL.h:
extern "C" __declspec(dllimport) int addC(int a, int b);
__declspec(dllimport) int addCpp(int a, int b);
DLL.cpp:
#include "DLL.h"
int addC(int a, int b) {
return a + b;
}
int addCpp(int a, int b) {
return a + b;
}
main.cpp:
#include "..DLL/DLL.h"
#include <stdio.h>
#include <windows.h>
int main() {
int a = 2;
int b = 1;
typedef int (*PFNaddC)(int,int);
typedef int (*PFNaddCpp)(int,int);
HMODULE hDLL = LoadLibrary(TEXT("../Debug/DLL.dll"));
if (hDLL != NULL)
{
PFNaddC pfnAddC = (PFNaddC)GetProcAddress(hDLL, "addC");
PFNaddCpp pfnAddCpp = (PFNaddCpp)GetProcAddress(hDLL, "addCpp");
printf("a=%d, b=%d\n", a,b);
printf("pfnAddC: %d\n", pfnAddC(a,b));
printf("pfnAddCpp: %d\n", pfnAddCpp(a,b)); //EXCEPTION ON THIS LINE
}
getchar();
return 0;
}
How can I import c++ functions for dynamic loading? I have found that the following code works with implicit loading by referencing the *.lib, but I would like to learn about dynamic loading.
Thank you to all in advance.
Update:
bindump /exports
1 00011109 ?addCpp##YAHHH#Z = #ILT+260(?addCpp##YAHHH#Z)
2 00011136 addC = #ILT+305(_addC)
Solution:
Create a conversion struct as
found here
Take a look at the
file exports and copy explicitly the
c++ mangle naming convention.
PFNaddCpp pfnAddCpp = (PFNaddCpp)GetProcAddress(hDLL, "?addCpp##YAHHH#Z");
Inevitably, the access violation on the null pointer is because GetProcAddress() returns null on error.
The problem is that C++ names are mangled by the compiler to accommodate a variety of C++ features (namespaces, classes, and overloading, among other things). So, your function addCpp() is not really named addCpp() in the resulting library. When you declare the function with extern "C", you give up overloading and the option of putting the function in a namespace, but in return you get a function whose name is not mangled, and which you can call from C code (which doesn't know anything about name mangling.)
One option to get around this is to export the functions using a .def file to rename the exported functions. There's an article, Explicitly Linking to Classes in DLLs, that describes what is necessary to do this.
It's possible to just wrap a whole header file in extern "C" as follows. Then you don't need to worry about forgetting an extern "C" on one of your declarations.
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllimport) int addC(int a, int b);
__declspec(dllimport) int addCpp(int a, int b);
#ifdef __cplusplus
} /* extern "C" */
#endif
You can still use all of the C++ features that you're used to in the function bodies -- these functions are still C++ functions -- they just have restrictions on the prototypes to make them compatible with C code.