Usar a DLL do Windows Kernel32

Pessoal,

Estou desenvolvendo um programa que precisa verificar no meu drive C quanto de espaço tenho, verifiquei que a DLL KERNEL32 tem a classe GetDiskFreeSpaceA, como faço para poder utiliza-la ?

Iniciei o programa da seguinte forma:

public class teste {

public static void main (String args[]) {

 System.loadLibrary("KERNEL32");
 COMO EXECUTO ESTA CLASSE --> GetDiskFreeSpaceA 

}
}

Obrigado

Carlos

Oi Carlos,

Venho tentando implementar algo parecido em Java (pegar o espaço em disco). Já coloquei uma mensagem no fórum e não tive resposta. Pensei então que poderíamos nos ajudar.
Pesquisei sobre native, embora não tenha conseguido fazer o código rodar vou te dar o caminho das pedras.

System.loadLibrary("KERNEL32");

Este codigo somente carrega a DLL, como vc já deveria saber. Para usar o método (ou função da DLL), vc deve declarar uma entrada native da função.

public static native boolean GetDiskFreeSpace(String rootPathName,
int[] sectorsPerCluster, int[] bytesPerSector,int[] numberOfFreeClusters, int[] totalNumberOfClusters);

Não tenho certeza que esses são os parâmetros da função, mas foi o que achei na Internet.
Depois vc tem que rodar um javah para gerar o header em C da sua classe java (.class).

javah -jni <classe>

Depois, teoricamente, bastaria rodar a classe.
Estou seguindo esses passos mas estou tendo o seguinte problema. Quando rodo a classe recebo o seguinte exception: java.lang.UnsatisfiedLinkError.
Posso colocar meu código aqui caso vc não consiga fazer todos os passos. Porém gostaria que vc me informasse se tiver avanço para rodar o método da DLL.

Cézar,

Seria legal você colocar o codigo, mas consegui um site em portugues que explica a DLL do Kernel32, ai vai ele:

http://www.numaboa.com/informatica/oiciliS/tabelas/apiKERNEL32.php#gdfs

Obrigado

Carlos

Oi Carlos,

Abaixo a classe que tentei rodar.

public class DiskSpace &#123;

	static&#123;
		System.loadLibrary&#40;&quot;KERNEL32&quot;&#41;;
	&#125;

/**
 * DiskSpace constructor comment.
 */
public DiskSpace&#40;&#41; &#123;
	super&#40;&#41;;
&#125;

/**
 * Starts the application.
 * @param args an array of command-line arguments
 */
public static void main&#40;java.lang.String&#91;&#93; args&#41; &#123;


			 int&#91;&#93; sectorsPerCluster = new int&#91;1&#93;;
			 int&#91;&#93; bytesPerSector = new int&#91;1&#93;;
			 int&#91;&#93; numberOfFreeClusters = new int&#91;1&#93;;
			 int&#91;&#93; totalNumberOfClusters = new int&#91;1&#93;;
			 if &#40;GetDiskFreeSpaceA&#40;&quot;c&#58;\&quot;, sectorsPerCluster, bytesPerSector,
								  numberOfFreeClusters, totalNumberOfClusters&#41;&#41;
			 &#123;
				 System.out.println&#40;&quot;There are &quot; + sectorsPerCluster&#91;0&#93; 
									*bytesPerSector&#91;0&#93;
									* numberOfFreeClusters&#91;0&#93; 
									+ &quot; free bytes on drive c.&quot;&#41;;
			 &#125;
			 else
			 &#123;
				 System.out.println&#40;&quot;GetDiskFreeSpace failed&quot;&#41;;
			 &#125;

&#125;
		 public static native boolean GetDiskFreeSpaceA&#40;String rootPathName,
			 int&#91;&#93; sectorsPerCluster, int&#91;&#93; bytesPerSector,
			 int&#91;&#93; numberOfFreeClusters, int&#91;&#93; totalNumberOfClusters&#41;;

&#125;

O java te permite chamar direto funções de uma biblioteca, voce tem que primeiro escrever 1 wrapper em C pra, so ai, chamar a função.

Não tem como escapar de usar JNI e se prepara pq ela é 1 porcaria de usar, principalmente se for manipular objetos ou arrays. Uma dica seria usar 1 programa chamado swig.

Olha na documentação da j2se 1.4.1 pelo tutorial de JNI

Saudades do SWIG… costumava salvar minha vida quando eu trabalhava com Python :slight_smile:

http://swig.sf.net

Oi louds,

Já deu para reparar que é bem chato usar JNI. Porém ainda quero conseguir usar, seja por aprendizado ou esperar um dia ser util.
Crie a classe, como foi colocada acima, gerei a include com javah, mas mesmo assim a classe não roda. Parece que não acha a DLL.
Se vc ver o site da sun…
http://developer.java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html#examp

… não tem muito mais o que fazer. Parece que está certo. O codigo não preciso implementar pois quero usar a DLL.
Se vc souber fazer, tem como mostrar um exemplo bem simples usando uma DLL qualquer do windows?

Abraços

carbaldo, deixe-me colocar de forma mais clara:

Em java é IMPOSSIVEL utilizar diretamente qualquer biblioteca do sistema, simplesmente não da!

Dito isso vou falar como isso pode ser contornado. Voce pode usar metodos nativos em java, que te permitem chamar 1 funcao escrita C. Porem o nome dessa função é o javah que define, gerar o header é apenas 1 pequena etapa do processo, ou seja, voce tem que escrever a ponte entre o codigo…

Eu tenho 1 exemplo bem simples do uso de jni
Posto ele mais tarde, assim que achar ele.

CV, voce já mexeu direto com a API de embedding do python?!?!?! Ela consegue fazer JNI parecer simples, pratica e facil. Amigo meu tem 1 projeto que eles tão dando embedding em python, ele fala como o negocio mais parece 1 gambi gigante que 1 API real.

Aqui vai 1 exemplo bem simples do uso de JNI, funciona ok em windows, com linux tem 1s problemas.

Sua classe:

public class IO
&#123;
	public static native int close&#40;int fd&#41;;

	static
	&#123;
		System.loadLibrary&#40;&quot;jni&quot;&#41;;
	&#125;

	public static void main&#40;String args&#91;&#93;&#41;
	&#123;
		System.out.println&#40;&quot;chamando close&quot;&#41;;
		int res = close&#40;30000&#41;;
		System.out.println&#40;&quot;res = &quot;+res&#41;;
	&#125;
&#125;

Oque ela supostamente faz? Ela chama o metodo close() do SO.

Oque fazer:
-compile usando javac normalmente
-gerar o header eh opcional, vc so precisa pra pegar a declaracao do metodo

Agora voce precisa compilar sua biblioteca em C (nome do arquivo eh IO.c):

#include &lt;jni.h&gt;
#ifdef WIN32
#include &lt;io.h&gt;
#else
#include &lt;unistd.h&gt;
#endif

JNIEXPORT jint JNICALL Java_IO_close
&#40;JNIEnv *env, jclass class, jint fd&#41;
&#123;
	return close&#40;fd&#41;;
&#125;

No windows pra compilar nao vou saber a sintaxe de antemao pra compiladores comerciais, se for mingw ou cygwin o comando eh quase o mesmo do linux
No linux: gcc -shared IO.c -o libjni.so
No windows: gcc -shared IO.c -o jni.dll
Pode nao funcionar de primeira, reclamando que nao achou jni.h, so voce usar ‘-I/onde_instalou_j2sdk/include’ com o comando de compilacao

Ok tento essa etapa feita, agora e so rodar, ou melhor quase se for linux.

No windows voce precisa ter os 2 arquivos IO.class e jni.dll no mesmo diretorio
ai so executar ‘java IO’

no linux tem 1 problema, a JVM procura pelas libs nos diretorios delas e nos definidos pela variavel de ambiente LD_LIBRARY_PATH. Entao se quiserem rodar com a lib, libjni.so, no mesmo diretorio basta usar: ‘LD_LIBRARY_PATH=. java IO’
ou
java -Djava.library.path=. IO

curioso que eu tentei usar System.setProperty(“java.library.path”, “.”) antes de chamar o loadLibrary() e nao funcionou, alguem sabe pq?

To de volta a todo vapor …

Vou responder as duvidas mais frequentes com relacao a JNI.

Bom oque o amigo quer e possivel ?
R: Sim e possivel.
Do jeito que esta fazendo ?
R: Nao desse jeito nao e possivel.
Entao como ?
R:Usando JNI
E dificil ?
R:Bom nao e :)mas nao e tao dificil

Bom deixemaos as perguntas de lado,nao se pode chamar funcoes propias do SO com java, e geralmente vejo as pessoas confundindo JNI com um metodo de acessar .dlls ou .sos nativas do SISTEMA OPERACIONAL, e as coisas nao funcionam assim, JNI e uma interface de programacao que da condicoes de escrever rotinas nativas (compiladas) dentro de sua classe JAVA, de modo se vc quer chamar GetDiskFreeSpaceEx tera de fazer isso numa dll usando as convesoes JNI, to fazendo uma aqui para postar aqui(mais tarde).Resumindo JNI nao e como as chamadas VB e DELPHI a Rotinas do SO.

Falow Galera …
t+

SIGA O COELHO BRANCO …

:evil: Ja que nenhum MANÉ quer ajudar a resolver o problema, fiz uma pesquisa na internet e encontrei um Site que tem a DLL necessária para saber o DISKSPACE do drive.

To vendo que este forum so tem gente que agita… alguns dizem “VOU RESPONDER ALGUMAS DUVIDAS”, po meu larga mão MANÉ e colocar o codigo para agente conseguir fazer as coisas ate com medo de ensinar… AGITADOR MANÉ VOCÊ NÃO SABE NEM O QUE É JAVA…

Ai Cézar, vai site para você e apaga para os MANE QUE DIZEM SER JAVEIRO EVANGELIZADOR não pegar, O site é http://www.jniwrapper.com

:!: :!: :!:

ninguem daqui tem obrigação de te responder nada, o pessoal ta aqui por que quer.
se tu quer alguem com obrigação de resolver os teus problemas,

R$ 60/h garanto que tu consegue alguem :slight_smile:

Ola Carlos,

Posso enviar um código que pode te ajudar. Não consegui usar JNI, mas acredito que esse código resolva seu problema.
O código pega o espaço em disco, e para isso rodei um bat que retorna a string de espaço em disco. E pego essa String no java. Só funciona em Windows e é uma solução nada elegante, mas é uma solução.
Não vou colocar o código aqui no fórum, pois ficaria grande. Por isso basta colocar o e-mail que envio.
Sobre o fórum já resolvi alguns problemas com ele, por isso não desanime. Acho que demos azar no tópico.

Abraços

ihhhh mais calma aí rapaz… :slight_smile:

olha nao sei sobre essa library KERNEL32 mas posso te mostrar um exemplo de JNI… vamos fazer um exemplo para somar dois números:

1 - Crie um arquivo *.c que vai ter o código nativo:

#include “HelloNative.h”
#include <stdio.h>

// metodo para utilizar a função “printf” do C
// método teste
JNIEXPORT void JNICALL Java_HelloNative_teste
(JNIEnv *env, jclass jc)
{
printf("Soma JNI

");
}

// método para ler um inteiro utilizando o velho “scanf”
// método readInt
JNIEXPORT jint JNICALL Java_HelloNative_readInt
(JNIEnv *env, jclass jc, jstring prompt)
{
int a = 0;
char buf[128];
const char *str = (*env)->GetStringUTFChars(env, prompt, 0);
printf("%s", str);
(*env)->ReleaseStringUTFChars(env, prompt, str);
scanf("%d", &a);
return a;

//return (*env)-&gt;NewStringUTF(env, buf);

}

// e este aqui server para somar blz???
JNIEXPORT jint JNICALL Java_HelloNative_soma
(JNIEnv *env, jclass jc, jint n1, jint n2)
{
return n1+n2;
}

2 - feito isso agora vamos escrever a implementação da clase Java que acessará este código nativo em C…

HelloNative.java

class HelloNative
{
// vc precisa declarar como “native”… pois a implementação do método está feita em outra linguagem… aqui vai só assinatura!
public static native void teste();
public static native int readInt(String prompt);
public static native int soma(int n1,int n2);

static
{
// este é o nome da dll -> depois vamos gerar uma HelloNative.dll
System.loadLibrary(“HelloNative”);
}

public static void main(String[] args)
{
// agora é só utilizar os métodos como se fossem feitos em Java mesmo!
HelloNative.teste();
int n1 = HelloNative.readInt("Numero 1: ");
int n2 = HelloNative.readInt("Numero 2: ");
int soma = HelloNative.soma(n1,n2);

System.out.println("

Soma: " + soma + "
");
}
}

3 - agora compile a classe:

javac HelloNative.java

4 - agora gere o arquivo *.h do C

javah -jni HelloNative

a saída será um arquivo HelloNative.h

lembre que no aquivo HelloNative.c vc faz um
#include “HelloNative.h”

5 - Agora a DLL:
já falaram outros meios de criar a dll aqui no fórum… eu costumo fazer assim…
precisa ter instalado o Microsoft Visual C++ para fazer deste jeito…

cl -IC:j2sdk1.4.1include -IC:j2sdk1.4.1includewin32 -LD HelloNative.c

6 - pronto, agora execute normalmente;

java HelloNative

isto dava um bom artigo :smiley:

ta errado este trecho, substitua por:

cl -IC:j2sdk1.4.1include -IC:j2sdk1.4.1includewin32 -LD HelloNative.c

[quote=“cesalvador”]:evil: Ja que nenhum MANÉ quer ajudar a resolver o problema, fiz uma pesquisa na internet e encontrei um Site que tem a DLL necessária para saber o DISKSPACE do drive.

To vendo que este forum so tem gente que agita… alguns dizem “VOU RESPONDER ALGUMAS DUVIDAS”, po meu larga mão MANÉ e colocar o codigo para agente conseguir fazer as coisas ate com medo de ensinar… AGITADOR MANÉ VOCÊ NÃO SABE NEM O QUE É JAVA…

Ai Cézar, vai site para você e apaga para os MANE QUE DIZEM SER JAVEIRO EVANGELIZADOR não pegar, O site é http://www.jniwrapper.com

:!: :!: :!:[/quote]

Curioso, se voce conseguiu isso STFG tao facilmente pq veio perguntar logo de cara, pq esse forum aqui não me parece ser 1 aviario.
Na próxima, também, tenta fazer download da documentação do j2se e RTFM.

PS: se voce não sabe oq significa STFG faz 1 Search no Google que vc descobre, e RTFM, da 1 Read em algum Manual do linux, constumam explicar muito bem esse termo.

[Flame ON]

O mais curioso é que a gente explica pq nao da pra fazer, discute algumas alternativas e o cara chama a gente de mané, e se vangloria pq descobriu a URL pra uma ferramentinha que faz o trabalho sujo que a gente explicou como fazer “no braço”…

Bom, acho que eu prefiro ser mané do que ter esse tipo de atitude, então.

[Flame OFF]

mane fui eu que dei 1 exemplo, teve outro ‘mané’ que deu 1 link pro SWING!! putz, que faz E-X-A-T-A-M-E-N-T-E oque ele queria, ele nem se deu o trabalho de ir ver o link. :!:

então tem mais “mané” aí… :oops: :oops: :oops:

putz !! mandei mal em mostrar um exemplo step-by-step para um cara que chama o pessoal de “mané”

mudando de assunto, eu nunca tinha ouvido falar neste SWIG… parece ser coisa boa!

Eu diria que SWIG é meio perigoso, depois de voce torrar 1 semana toda pra usar 1 API sacal para falar com java ou python, por exemplo, vc descobre SWING e se da conta que em 30min vc teria feito o mesmo serviço e ainda por cima ate melhor. Da vontade de matar alguem…