我是C编程的新手并试图写一个简单的例子.我试图在类型实现上进行抽象,并简单地使用typedef
和指定我可以对此类型执行的操作.我知道那时候类型是不完整的,但我打算把它完成到c
-file,而不是标题.就这个:
test.h
#ifndef _TEST_H
#define _TEST_H
typedef my_type_t;
void init(my_type_t **t);
#endif //_TEST_H
Run Code Online (Sandbox Code Playgroud)
test.c
#include <stdlib.h>
#include "test.h"
// implementation details
struct my_type_t{ //<---- completening my_type_t to be a struct with 1 field
int field;
};
void init(struct my_type_t **t){ //<--- error: conflicting type for init
*t = malloc(sizeof(struct my_type_t));
(*t) -> field = 42;
}
Run Code Online (Sandbox Code Playgroud)
这样的事情可能吗?我希望实现完全隐藏有关实际类型定义的所有细节,只暴露可以用它完成的操作.
UPD:如果我们重写c
-file如下:
#include <stdlib.h>
#include "test.h"
struct internal_my_type_definition_t{
int field;
};
void init(my_type_t **t){
struct internal_my_type_definition_t *st = …
Run Code Online (Sandbox Code Playgroud) 问题是我们可以缓存jclass
并jmethodID
跨不同的JNI方法调用吗?
尝试通过缓存jclass
和jmethodID
其他JNI方法调用创建某个特定类的对象时,遇到了一些奇怪的行为。
这是一个简单的示例:
public class Main {
static {
System.loadLibrary("test-crash");
}
public static void main(String args[]) throws InterruptedException {
Thread.sleep(20000);
doAnotherAction(doSomeAction());
}
private static native long doSomeAction();
private static native void doAnotherAction(long ptr);
}
public class MyClass {
public int a;
public MyClass(int a) {
if(a == 10){
throw new IllegalArgumentException("a == 10");
}
this.a = a;
}
}
Run Code Online (Sandbox Code Playgroud)
JNI函数所做的只是创建类的对象MyClass
。该函数doSomeAction
返回一个指向已缓存的jclass
和的指针jmethodID
。这是本机方法的实现:
struct test{
jclass mc; …
Run Code Online (Sandbox Code Playgroud) 问题:大多数宏定义甚至头文件都不会被 IDE 查找,因为 IDE 配置中没有指定包含路径。它禁止自动完成和导航。
这是我的Makefile
:
#-Wno-declaration-after-statement
ccflags-y := -std=gnu11 -Wno-declaration-after-statement -Werror
obj-m += pfsw.o
pfsw-objs := src/init.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Run Code Online (Sandbox Code Playgroud)
我运行make V=1
并注意到编译命令和包含路径实际上非常麻烦(计算 Linux 特定-include
的参数):
gcc -Wp,-MD,/home/memyself/lkm/procfs_write/src/.init.o.d -nostdinc
-isystem /usr/lib/gcc/x86_64-linux-gnu/7/include
-I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi
-I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi
-include ./include/linux/kconfig.h -Iubuntu/include -include ./include/linux/compiler_types.h
-D__KERNEL__
//tons of options ommitted...
-c -o /home/memyself/lkm/procfs_write/src/init.o
/home/memyself/lkm/procfs_write/src/init.c
Run Code Online (Sandbox Code Playgroud)
问题:有没有办法生成compile-command.json
通知 IDE 有关包含路径的信息?还是唯一的解决办法是手动将include路径一一传递给IDE?
在了解我的应用程序(I/O 密集型)的分析结果时,我面临copy_user_enhanced_fast_string
成为最热门的区域之一。在用户空间和内核空间之间复制时调用它。x86 上的实现如下所示:
ENTRY(copy_user_enhanced_fast_string)
ASM_STAC
cmpl $64,%edx
jb .L_copy_short_string /* less then 64 bytes, avoid the costly 'rep' */
movl %edx,%ecx
1: rep
movsb
xorl %eax,%eax
ASM_CLAC
ret
.section .fixup,"ax"
12: movl %ecx,%edx /* ecx is zerorest also */
jmp .Lcopy_user_handle_tail
.previous
_ASM_EXTABLE_UA(1b, 12b)
ENDPROC(copy_user_enhanced_fast_string)
Run Code Online (Sandbox Code Playgroud)
为什么不vmovaps
/vmovups
用于那个?不是已经证明 AVX 在复制可用的地方没有性能优势吗?
根据c ++标准:
任何翻译单元都不得包含任何变量,函数,类类型,枚举类型或模板的多个定义.
//--translation_unit.cpp--//
int a;
void foo()
{
int a; //Second defention of a. ODR fails.
}
Run Code Online (Sandbox Code Playgroud)
你能解释一下ODR实际上是如何运作的吗?
如果在对象的生命周期结束之后并且在重用或释放对象占用的存储之前,则在原始对象占用的存储位置创建新对象,指向原始对象的指针,引用引用原始对象,或者原始对象的名称将自动引用新对象,并且一旦新对象的生命周期开始,就可以用来操纵新对象,如果:
- 新对象的存储正好覆盖原始对象占用的存储位置,以及
- 新对象与原始对象的类型相同(忽略顶级cv限定符),和
- 原始对象的类型不是const限定的,如果是类类型,则不包含任何类型为const限定的非静态数据成员或引用类型,以及
- 原始对象是类型为T的派生程度最高的对象(1.8),新对象是类型为T的派生程度最高的对象(也就是说,它们不是基类子对象).
目前尚不清楚什么样的类型是什么意思?动态还是静态?我认为,它是静态类型,因为否则后一种限制毫无意义.
为什么我不能通过PrintWriter写大量数据?
String result = acquireLengthyData();
PrintWriter out = new PrintWriter("D:/log.txt");
out.println(result);
Run Code Online (Sandbox Code Playgroud)
哪里result.lenght() = 189718
.但是有些数据缺失了log.txt
.为什么?如何正确写入文件?
我有以下课程:
package org.gradle;
public class Supcl {
public class Inner extends Supsupcl {
public Inner(int a) {
System.out.println(a);
}
}
}
Run Code Online (Sandbox Code Playgroud)
和
package org.gradle;
public class Subcl extends Supcl.Inner {
public Subcl() {
Supcl.Inner.super(34); //error: No enclosing instance of type Supcl is
//available due to some
//intermediate constructor invocation
}
}
Run Code Online (Sandbox Code Playgroud)
和班级Supsupcl
:
package org.gradle;
public class Supsupcl {}
Run Code Online (Sandbox Code Playgroud)
如果我尝试更换Supcl.Inner.super(34);
与super(34);
同样的错误会发生.怎么办?
我写了以下最简单的脚本:
task init << {
println "init";
}
task hello(dependsOn: init) << {
println "hello";
}
task super(dependsOn: hello) << {
println "super"
}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试执行时出错gradle super
:
build file 'D:\gradle\build.gradle': 9: Constructor call must be the first statement in
a constructor. at line: 9 column: 12.
File: build_69b6a3lkqqtk7j84lsls47ccta @ line 9, column 12.
task super(dependsOn: hello) << {
Run Code Online (Sandbox Code Playgroud)
有什么问题?
我上课了ViewPartner.java
.该课程如下所示
public class ViewPartner {
private Integer id;
//GET, SET
//Other properties
}
Run Code Online (Sandbox Code Playgroud)
我有两个List<ViewPartner>
,说lst1
和lst2
我需要的人以下列方式结合起来:如果有一个ViewPartner
具有相同id
均lst1
与lst2
我们的投入ViewPartner
从lst1
,和来自两个列表并非如此.
我使用的是apache commons
和google guava
......也许有一些瞬间的方法?
List
在这里严格使用对我来说并不重要.
java ×4
c ×2
c++ ×2
linux ×2
linux-kernel ×2
assembly ×1
collections ×1
constructor ×1
gradle ×1
groovy ×1
header ×1
jvm ×1
jvm-hotspot ×1
makefile ×1
typedef ×1
types ×1
x86-64 ×1