Skip to content

Commit a184206

Browse files
committed
Merge pull request #39 from OSVR/adjust-search-path
Improve DLL search path fixer.
2 parents 62319a6 + 7962060 commit a184206

3 files changed

Lines changed: 149 additions & 73 deletions

File tree

OSVR-Unity/Assets/OSVRUnity/src/ClientKit.cs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,9 @@ private void EnsureStarted()
7575
}
7676
}
7777

78-
/// <summary>
79-
/// Static constructor that enhances the DLL search path to ensure dependent native dlls are found.
80-
/// </summary>
81-
static ClientKit()
82-
{
83-
DLLSearchPathFixer.fix();
84-
}
85-
8678
void Awake()
8779
{
80+
DLLSearchPathFixer.fix();
8881
DontDestroyOnLoad(gameObject);
8982
}
9083
void Start()
@@ -102,7 +95,6 @@ void OnEnable()
10295
void FixedUpdate()
10396
{
10497
EnsureStarted();
105-
//Debug.Log("ClientKit FixedUpdate: frame # " + Time.frameCount + " " + Time.time);
10698
contextObject.update();
10799
}
108100

Lines changed: 143 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,143 @@
1-
/// OSVR-Unity Connection
2-
///
3-
/// <copyright>
4-
/// Copyright 2014 Sensics, Inc.
5-
///
6-
/// Licensed under the Apache License, Version 2.0 (the "License");
7-
/// you may not use this file except in compliance with the License.
8-
/// You may obtain a copy of the License at
9-
///
10-
/// http://www.apache.org/licenses/LICENSE-2.0
11-
///
12-
/// Unless required by applicable law or agreed to in writing, software
13-
/// distributed under the License is distributed on an "AS IS" BASIS,
14-
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15-
/// See the License for the specific language governing permissions and
16-
/// limitations under the License.
17-
/// </copyright>
18-
19-
using System;
20-
using System.IO;
21-
using System.Text;
22-
23-
namespace OSVR
24-
{
25-
namespace Unity
26-
{
27-
public class DLLSearchPathFixer
28-
{
29-
/// <summary>
30-
/// Call in a static constructor of an object depending on native code.
31-
///
32-
/// It is required if that native DLL being accessed depends on other native DLLs alongside it.
33-
/// </summary>
34-
public static void fix()
35-
{
36-
string[] dllPaths = {
37-
"Assets" + Path.DirectorySeparatorChar + "Plugins",
38-
"Assets"+ Path.DirectorySeparatorChar + "Plugins"+ Path.DirectorySeparatorChar + "x86", // todo don't hardcode this
39-
"StreamingAssets"+ Path.DirectorySeparatorChar + "Plugins",
40-
"StreamingAssets"+ Path.DirectorySeparatorChar + "Plugins"+ Path.DirectorySeparatorChar + "x86" // todo don't hardcode this
41-
};
42-
// Amend DLL search path - see http://forum.unity3d.com/threads/dllnotfoundexception-when-depend-on-another-dll.31083/#post-1042180
43-
// for original inspiration for this code.
44-
string currentPath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process);
45-
string[] currentPaths = currentPath.Split(Path.PathSeparator);
46-
StringBuilder paths = new StringBuilder();
47-
foreach (string dllPath in dllPaths)
48-
{
49-
String fullDllPath = Environment.CurrentDirectory + Path.DirectorySeparatorChar + dllPath;
50-
if (Array.IndexOf(currentPaths, fullDllPath) < 0)
51-
{
52-
paths.AppendFormat("{1}{0}", Path.PathSeparator, fullDllPath);
53-
}
54-
}
55-
// Keeps our new paths in front.
56-
paths.Append(currentPath);
57-
Environment.SetEnvironmentVariable("PATH", paths.ToString(), EnvironmentVariableTarget.Process);
58-
}
59-
60-
}
61-
}
62-
}
1+
/// OSVR-Unity Connection
2+
///
3+
/// <copyright>
4+
/// Copyright 2014 Sensics, Inc.
5+
///
6+
/// Licensed under the Apache License, Version 2.0 (the "License");
7+
/// you may not use this file except in compliance with the License.
8+
/// You may obtain a copy of the License at
9+
///
10+
/// http://www.apache.org/licenses/LICENSE-2.0
11+
///
12+
/// Unless required by applicable law or agreed to in writing, software
13+
/// distributed under the License is distributed on an "AS IS" BASIS,
14+
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
/// See the License for the specific language governing permissions and
16+
/// limitations under the License.
17+
/// </copyright>
18+
19+
using System;
20+
using System.Collections.Generic;
21+
using System.IO;
22+
using UnityEngine;
23+
24+
namespace OSVR
25+
{
26+
namespace Unity
27+
{
28+
public class DLLSearchPathFixer
29+
{
30+
/// <summary>
31+
/// Call in a static constructor of an object depending on native code.
32+
///
33+
/// It is required if that native DLL being accessed depends on other native DLLs alongside it.
34+
/// </summary>
35+
public static void fix()
36+
{
37+
// Amend DLL search path - see http://forum.unity3d.com/threads/dllnotfoundexception-when-depend-on-another-dll.31083/#post-1042180
38+
// for original inspiration for this code.
39+
40+
var fixer = new DLLSearchPathFixer();
41+
fixer.ConditionallyAddRelativeDir("Plugins");
42+
fixer.ConditionallyAddRelativeDir(new List<String>() { "Plugins", IntPtr.Size == 4 ? "x86" : "x86_64" });
43+
fixer.ApplyChanges();
44+
}
45+
46+
/// <summary>
47+
/// Constructor for private use as a helper within the static fix() method.
48+
/// </summary>
49+
private DLLSearchPathFixer()
50+
{
51+
var currentPath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process);
52+
//Debug.Log(String.Format("Old PATH: {0}", currentPath));
53+
OrigDirs = new List<string>(currentPath.Split(Path.PathSeparator));
54+
UnityDataDir = Application.dataPath;
55+
UnityDataDirBackslashed = Application.dataPath.Replace("/", "\\");
56+
}
57+
58+
/// <summary>
59+
/// Update the process environment PATH variable to contain the full list (entries new and old) of directories.
60+
/// </summary>
61+
private void ApplyChanges()
62+
{
63+
// Combine new and old dirs
64+
var allDirs = new List<String>(NewDirs);
65+
allDirs.AddRange(OrigDirs);
66+
67+
var newPathString = String.Join(Path.PathSeparator.ToString(), allDirs.ToArray());
68+
//Debug.Log(String.Format("New PATH: {0}", newPathString));
69+
Environment.SetEnvironmentVariable("PATH", newPathString, EnvironmentVariableTarget.Process);
70+
}
71+
72+
/// <summary>
73+
/// If a directory specified relative to the Unity data dir is not yet in the PATH, add it.
74+
/// </summary>
75+
/// <param name="dirComponents">Components of a directory name relative to the Unity data dir.</param>
76+
private void ConditionallyAddRelativeDir(List<string> dirComponents)
77+
{
78+
ConditionallyAddRelativeDir(PathTools.Combine(dirComponents));
79+
}
80+
81+
/// <summary>
82+
/// If a directory specified relative to the Unity data dir is not yet in the PATH, add it.
83+
/// </summary>
84+
/// <param name="dirComponents">A directory name relative to the Unity data dir.</param>
85+
private void ConditionallyAddRelativeDir(string relativePortion)
86+
{
87+
if (IsRelativeDirIncludedInPath(relativePortion))
88+
{
89+
// early out.
90+
return;
91+
}
92+
NewDirs.Add(PathTools.Combine(UnityDataDir, relativePortion));
93+
}
94+
95+
/// <summary>
96+
/// Checks to see if a directory specified relative to the Unity data dir is included in the path so far.
97+
/// It checks using both forward-slashed and backslashed versions of the Unity data dir.
98+
/// </summary>
99+
/// <param name="relativePortion">Directory relative to the Unity data dir</param>
100+
/// <returns>true if the given directory is included in the path so far</returns>
101+
private bool IsRelativeDirIncludedInPath(string relativePortion)
102+
{
103+
return IsIncludedInPath(PathTools.Combine(UnityDataDir, relativePortion)) || IsIncludedInPath(PathTools.Combine(UnityDataDirBackslashed, relativePortion));
104+
}
105+
106+
/// <summary>
107+
/// Checks to see if a directory is included in the path so far (both new and old directories).
108+
/// </summary>
109+
/// <param name="dir">Directory name</param>
110+
/// <returns>true if the given directory name is found in either the new or old directory lists.</returns>
111+
private bool IsIncludedInPath(string dir)
112+
{
113+
return NewDirs.Contains(dir) || OrigDirs.Contains(dir);
114+
}
115+
116+
private string UnityDataDir;
117+
private string UnityDataDirBackslashed;
118+
private List<string> NewDirs = new List<string>();
119+
private List<string> OrigDirs;
120+
121+
/// <summary>
122+
/// Utilities for combining path components with a wider variety of input data types than System.IO.Path.Combine
123+
/// </summary>
124+
private class PathTools
125+
{
126+
internal static string Combine(string a, string b)
127+
{
128+
return Path.Combine(a, b);
129+
}
130+
131+
internal static string Combine(string[] components)
132+
{
133+
return String.Join(Path.DirectorySeparatorChar.ToString(), components);
134+
}
135+
136+
internal static string Combine(List<String> components)
137+
{
138+
return PathTools.Combine(components.ToArray());
139+
}
140+
}
141+
}
142+
}
143+
}

OSVR-Unity/CHANGES.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
This is an abbreviated changelog for the OSVR Unity Plugin.
44

55
Use git for a full changelog.
6-
##Recent Changes (updated 28-March-2015)
7-
##External Json File v0.1-56-gf2d8bab (20-March-2015)
6+
##Recent Changes (updated 31-March-2015)
7+
##DLL Search Path v0.1-69-gb80966b (31-March-2015)
8+
- The built executable will now find the plugins it needs in the _Data folder. Previously, the executable had to be in the same directory with Assets/Plugins. That is no longer necessary.
9+
10+
##External Json File v0.1-56-gf2d8bab (28-March-2015)
811
- The JSON file containing display configuration can now be read from a file at runtime. To do this, add a config file "hmd.json" to the _Data folder that is created in a build. The format of the JSON file has not changed at all. It is the same file you would drag-and-drop onto the DisplayInterface component on your VRDisplayTracked prefab. If "hmd.json" does not exist in the Data folder (and it won't by default unless you put it there), then the plugin will look for the JSON file assigned in the DisplayInterface component in your scene. If that also has not been assigned, it will fall back to reading OSVR's /display parameter (this will eventually be the default).
912

1013
##Distortion v0.1-55-g046c709(20-March-2015)

0 commit comments

Comments
 (0)