golang編譯so
❶ 如何Golang開發Android應用
環境配置好復雜,我不得不嘮叨幾句。
需要下載golang1.4rc版,下載ndk,然後編譯。 然後用go get 下載gobind這個工具, 然後,將寫好的代碼用gobind轉化下,然後使用特殊的編譯命令,將代碼編譯成.so文件,將生成的相關文件,放到android studio的項目中。然後java代碼中,利用jni調用引用的代碼。
... 好,接著往下看吧。
環境准備
一台linux 64的機器
一個帶有AndroidStudioIDE的開發機器
因為環境配置實在復雜,所以我們引入的docker。
docker pull codeskyblue/docker-goandroid
docker run --rm -ti codeskyblue/docker-goandroid bash
cd example; echo "view example projects
docker起來之後,什麼就都配置好了,NDK啦,java啦,GO的環境變數了,等等,並且還預裝了vim,gradle,tmux,git,syncthing,svn
開始寫代碼
寫代碼之前,先約定下目錄結構
go的代碼都放在src/golib下,編譯使用make.bash編譯腳本,看下這個文件樹
.
|-- app.iml
|-- build.gradle
|-- libs/armeabi-v7a # go編譯生成的so文件
| `-- libgojni.so
|-- main.go_tmpl # 一個模板文件,先不用管它
|-- make.bash # 編譯腳本,用來生成.so和Java代碼
`-- src
|-- golib
| |-- hi
| | |-- go_hi�0�2�0�2�0�2 # 自動生成的代碼
| | | `-- go_hi.go
| | `-- hi.go # 需要編寫的代碼
| `-- main.go
`-- main
|-- AndroidManifest.xml
|-- java
| |-- go # 自動生成的代碼
| | |-- Go.java
| | |-- Seq.java
| | `-- hi
| | `-- Hi.java
| `-- me/shengxiang/gohello # 主要的邏輯代碼
| `-- MainActivity.java
`-- res
我已經寫了一個例子,先直接搞下來
編譯下,試試行不行(就算不行問題應該也不大,因為大問題都被我消滅了)
cd GoHello/app
./make.bash
../gradlew build
一切順利的話在build/outputs/apk下應該可以看到app-debug.apk這個文件。(劇透下,這個文件只有800多K)
編譯好的我放到qiniu上了,可以點擊下載看看
下面可以嘗試改改,我拋磚引玉說下
打開hi.go這個文件
hi.go的內容,比較簡單,我們寫Go代碼主要就是這部分
// Package hi provides a function for saying hello.
package hi
import "fmt"
func Hello(name string) {
fmt.Printf("Hello, %s!\n", name)
return "(Go)World"
}
文件末尾添加下面這行代碼
func Welcome(name string) string {
return fmt.Sprintf("Welcome %s to the go world", name)
}
使用./make.bash重新編譯下
打開MainActivity.java 修改下OnClickListener事件
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String message = Hi.Welcome("yourname");
Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
}
});
編譯運行下,把生成的apk安裝到手機上試試。
原理解讀(有興趣的接著看)
首先說下gobind這個工具。
go_hi/go_hi.go這個文件時通過gobind這個工具生成的,用來配合一個簡單的程序,生成.so文件
// go_hi.go
package go_hi
import (
"golang.org/x/mobile/bind/seq"
"example/hi"
)
func proxy_Hello(out, in *seq.Buffer) {
param_name := in.ReadUTF16()
hi.Hello(param_name)
}
func init() {
seq.Register("hi", 1, proxy_Hello)
}
這個簡單的程序內容是這樣的
// main.go
package main
import (
"golang.org/x/mobile/app"
_ "golang.org/x/mobile/bind/java"
_ "example/hi/go_hi"
)
func main() {
app.Run(app.Callbacks{})
}
src/MyActivity.java文件內容是這樣的
import ...
import go.Go; // 引入Go這個包
import go.hi.Hi; // gobind生成的代碼
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Go.init(getApplicationContext()); // 初始化兩個線程
Hi.Hello("world");
}
}
其中有一句Go.init(...)這里再看go.Go這個包是什麼樣子的
public final class Go {
// init loads libgojni.so and starts the runtime.
public static void init(Context context) {
... 判斷該函數是否該執行的代碼 -- 省略 --
System.loadLibrary("gojni"); // gojni需要這句
new Thread("GoMain") {
public void run() {
Go.run(); // run()是一個native方法
}
}.start();
Go.waitForRun(); // 這個也是一個native方法
// 這部分可以理解為,啟動了一個後台線程不斷的接收結果到緩存中。
new Thread("GoReceive") {
public void run() { Seq.receive(); }
}.start();
}
private static boolean running = false;
private static native void run();
private static native void waitForRun();
}
MyActivity.java中還有段代碼是 Hi.Hello("world");,打開Hi.java路徑在src/go/hi/Hi.java,這個文件也是gobind生成的,是用來給java方便的調用.so文件
// Hi.java
// File is generated by gobind. Do not edit.
package go.hi;
import go.Seq;
public abstract class Hi {
private Hi() {} // uninstantiable
public static void Hello(String name) {
go.Seq _in = new go.Seq();
go.Seq _out = new go.Seq();
_in.writeUTF16(name);
Seq.send(DESCRIPTOR, CALL_Hello, _in, _out); // 下面接著說
}
private static final int CALL_Hello = 1;
private static final String DESCRIPTOR = "hi";
}
Seq.send這部分實際上最終調用的是一段go代碼
func Send(descriptor string, code int, req *C.uint8_t, reqlen C.size_t, res **C.uint8_t, reslen *C.size_t) {
fn := seq.Registry[descriptor][code]
in := new(seq.Buffer)
if reqlen > 0 {
in.Data = (*[maxSliceLen]byte)(unsafe.Pointer(req))[:reqlen]
}
out := new(seq.Buffer)
fn(out, in)
seqToBuf(res, reslen, out)
}
轉載僅供參考,版權屬於原作者。祝你愉快,滿意請採納哦
❷ golang如何把全部依賴都編譯進一個文件
個人覺得golang十分適合進行網游伺服器端開發,寫下這篇文章總結一下。從網游的角度看:要成功的運營一款網游,很大程度上依賴於玩家自發形成的社區。只有玩家自發形成一個穩定的生態系統,游戲才能持續下去,避免鬼城的出現。
❸ golang工作中是編譯好再放到伺服器上嗎
一般是編譯好再放到伺服器上去的。
哪怕是跨平台的交叉編譯。
質量是不可能有下降的。
對於非go語言的話,主要是可以通過調整編譯時的參數不同,來啟用各種優化。
實際業務上,大部分也是通過源或者docker來安裝的。
❹ sublime text 3 怎麼編譯golang
1.安裝git
因為golang是通過git來管理遠程包的,所以我們首先要安裝git
git安裝比較簡單,直接下一步即可(在Windows Explorer integration選項中將「Git Bash here」和「Git GUI here」打對勾),需要了解具體安裝的可以看這里。
2.安裝Golang
1) 首先到https://golang.org/dl/選擇適合你系統的安裝包
2)我這里選擇的是:go1.4.2.windows-amd64.msi,下載完成安裝到指定目錄即可。我這里是(E:\Go)。
3)安裝完成後環境變數已經自動設置好了,可以呼出cmd命令行輸入命令查看
> go env
可以看到,已經出現go命令了。如果你的不能出現,那可能是環境變數設置的問題。
進入我的電腦->高級設置->環境變數查看下,GOROOT變數是否存在,以及Path變數中是否也設置了GOROOT。沒有的話,新增一個GOROOT變數,路徑則輸入你剛剛安裝完成後Go的根目錄,如我的是:E:\Go\。然後編輯Path變數,在最後面新增";%GOROOT%bin"。
4)go命令依賴一個環境變數:GOPATH,這不是Go的安裝目錄,而是你的工作(工程)目錄(你的代碼都會在該目錄下)。GOPATH可以有多個,windows以分號(;)進行區分,Linux系統是冒號(:),當有多個GOPATH時,默認會將go get的內容放在第一個目錄下。這里我們新建一個GOPATH變數,以我的為例:F:\mygo。
3.安裝Sublime Text3
注意:sublime是收費軟體,不注冊也可以正常使用,只是保存次數達到一定的數量的時候會提示購買;忽略後可以正常使用。
這里需要安裝一個sublime的pakcage control功能,用於接下來安裝sublime插件。
1)在打開軟體後,按下快捷鍵 Ctrl+`,(`這個符號為英文半形模式下,按下 Tab 鍵上方、數字鍵1左邊的那個按鍵),此時會打開一個命令窗口,復制並輸入以下內容,最後回車:
import urllib.request,os,hashlib; h = '' + ''; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)
2)重啟sublime之後,你就可以發現在 Preferences 這個菜單下出現了菜單項 Package Control,如圖:
4. 安裝GoSublime插件
1)在sublime中,按住快捷鍵 shift + ctrl + p,在彈出框中輸入install package,如圖:
2)回車,會出現如下圖(可能需要稍微等待下,可以看sublime最下面的狀態):
3)輸入gosublime,回車(可能需要稍微等待下,可以看sublime最下面的狀態),如圖:
4)gosublime安裝完成後,Preferences -> package settings -> GoSublime -> Settings - Uesrs需要配置下GOPATH,GOROOT,如圖:
5)在打開的窗口中輸入以下內容,路徑請自行替換,ctrl+s保存。
{
"env": {
"GOPATH": "F:/mygo",
"GOROOT": "E:/Go"
}
}
6)重啟sublime,在GOPATH中的src新建一個hello.go文件,可以看到代碼自動補全已經出來了,:)
至此,sublime text3 + golang 安裝完成。
❺ golang調用so庫同步函數停止
測試動態庫步驟:
1、test_so.h
2、test_so.c
3、生成so
4、復制so文件到Go項目目錄
Go項目目錄
1、load_so.h
2、load_so.c
3、test.go
4、Go項目目錄要放在$GOPATH/src/目錄下,這也是正常操作。
test目錄為Go項目,里邊是上述創建的所有源碼文件。
在$GOPATH/src/test/里直接使用gobuild編譯生成test二進制文件,此處需要注意執行路徑。
問題
1、/**/注釋的代碼下一行一定是import「C」,中間不能有空行
2、importC必須單獨一行,不能和其它庫一起導入
3、有人編譯的時候會報錯:
這個主要是執行目錄問題,一定要在$GOPATH/src/項目/目錄下,用gobuild執行,gobuild後邊不要有任何文件名。
或者用gorun.運行,或者goruntest,test是項目名。不能用goruntest.go。
4、還有人報這個錯:test.go文件里的cgoLDFLAGS:-ldl這一行不要刪掉。
❻ 怎麼編譯golang寫的程序為系統服務
設置GOPATH,這個環境變數指向你的projectDir(工程目錄),形如:GOPATH=/home/user/ext:/home/user/projectDir (可以設置多個工程目錄,linux下用冒號分隔,windows下用分號分隔)
創建工程文件夾projectDir
在projectDir下創建src目錄
在src下創建區分包的文件夾myDir
在myDir下創建包pkgDir
在pkgDir下創建package source源代碼文件,這些文件的package都是pkgDir
❼ 如何利用Golang為python編寫模塊
Go裡面需要顯示的引入C模塊, 讓編譯器支持生成動態鏈接庫, 並且在代碼中可以使用C語言的數據類型,這個至關重要.Calling Go code from Python code摘取一個最簡單例子
//libadd.go
packagemain
import"C"
//exportadd
funcadd(left,rightint)int{
returnleft+right
}
funcmain(){
}
gobuild-buildmode=c-shared-olibadd.solibadd.go
fromctypesimportcdll
lib=cdll.LoadLibrary('./libadd.so')
print("LoadedgogeneratedSOlibrary")
result=lib.add(2,3)
print(result)
❽ intellij idea15的golang插件怎麼配置
將下載的zip包解壓,然後執行 File -> open 操作打開該項目
打開該項目後,進行 SDK 和 模塊配置
執行操作 File -> Project Structure 打開項目結構配置窗口
如下圖配置,SDKs 中設置 JDK、 IDEA 這兩個的路徑(圖上的 Go sdk 你先別管他,你現在還操作不了的)
IDEA 的sdk 其實就是軟體安裝目錄
然後是模塊設置 Moles
設置當前模塊的SDK依賴,如果不設置這里,則編譯時會出現下面的錯誤:
我在這里莫名其妙了好半天才找到原因
然後選擇 ro.redeul.google.go 包進行編譯,如圖:
這里如果沒有出現 error 則編譯成功。
3. 生成插件 jar 安裝包
選擇 Build -> Prepare Plugin mole ... For Deployment 將會生成一個google-go-language.jar 的文件在項目根目錄下
4. 安裝插件:
選擇 File->settings -> Plugins -> install plugins from disk 在右下角
選擇剛剛生成的 jar 文件將自動安裝插件,然後重啟軟體就好了
5. 下載安裝 go sdk
http://golang.so/dl/1.4/
選擇你對應的系統版本安裝吧,
然後一些系統環境變數配置,
參考:
新建 變數名:GOBIN 變數值 :C:\Go\bin
新建 變數名:GOARCH 變數值:386
如果是64位系統 變數值為amd64
新建 變數名:GOOS 變數值:windows
新建 變數名: GOROOT 變數值:C:\Go
新建 變數名: GOPATH 變數值:C:\my\go\project
\my\go\project 是你的項目目錄
編輯 Path 在Path的變數值的最後加上 ;C:\Go\bin
之後你新建項目就可以看到 go 的圖標啦
新建好項目 hello world 一下吧 o(∩_∩)o 哈哈 ,可以開始開發你牛逼的 GO 項目了
好了先就這樣吧
❾ golang 如何創建,編譯,打包go語言的源代碼和工程
1.最簡單的方法:
public static String reverse1(String str)
{ return new StringBuffer(str).reverse().toString();
}
2.最常用的方法:
public static String reverse3(String s)
{ char[] array = s.toCharArray();
String reverse = ""; //注意這是空串,不是null
for (int i = array.length - 1; i >= 0; i--)
reverse += array[i];
return reverse;
}
3.常用方法的變形:
public static String reverse2(String s)
{ int length = s.length();
String reverse = ""; //注意這是空串,不是null
for (int i = 0; i < length; i++)
reverse = s.charAt(i) + reverse;//在字元串前面連接, 而非常見的後面
return reverse;
}